diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index d631985e8207b53d3b94d415596be01c36d27f1d..576dbfd2c2f1836fadcf374b1b571373550258ce 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -1022,6 +1022,11 @@ BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera) return TRUE; } +U32 LLOcclusionCullingGroup::getLastOcclusionIssuedTime() +{ + return mOcclusionIssued[LLViewerCamera::sCurCameraID]; +} + void LLOcclusionCullingGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index 7f2ca6ed2d47d610ec71fa68dd4c304fa47c3a41..e210d8f47833147d9877afe155904e136bbf5cd0 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -320,6 +320,7 @@ class LLOcclusionCullingGroup : public LLviewerOctreeGroup BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } BOOL needsUpdate(); + U32 getLastOcclusionIssuedTime(); //virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 64b25f4b0b04edba7ff0b249f01489013f57abb6..dd4c7f2affbe3a5867b3a226ae716f9ed7f1b6dc 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -992,7 +992,7 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) //add the visible entries void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) { - if(mDead || !entry) + if(mDead || !entry || !entry->getEntry()) { return; } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 93daf2e1713fbdd316b2cafc4c07f771e279a47a..f23375adfa4f114875d753891b94b66fdf2d3083 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -244,6 +244,13 @@ U32 LLVOCacheEntry::getMinFrameRange()const void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) { llassert(entry != NULL); + llassert(entry->getParentID() == mLocalID); + llassert(entry->getEntry() != NULL); + + if(!entry || !entry->getEntry() || entry->getParentID() != mLocalID) + { + return; + } mChildrenList.push_back(entry); } @@ -392,9 +399,10 @@ void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) class LLVOCacheOctreeCull : public LLViewerOctreeCull { public: - LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion) + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion, LLVOCachePartition* part) : LLViewerOctreeCull(camera), - mRegionp(regionp) + mRegionp(regionp), + mPartition(part) { mLocalShift = shift; mUseObjectCacheOcclusion = (use_object_cache_occlusion && LLPipeline::sUseOcclusion); @@ -415,6 +423,7 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull if (group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { + mPartition->addOccluders(group); return true; } } @@ -466,9 +475,10 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull } private: - LLViewerRegion* mRegionp; - LLVector3 mLocalShift; //shift vector from agent space to local region space. - bool mUseObjectCacheOcclusion; + LLVOCachePartition* mPartition; + LLViewerRegion* mRegionp; + LLVector3 mLocalShift; //shift vector from agent space to local region space. + bool mUseObjectCacheOcclusion; }; S32 LLVOCachePartition::cull(LLCamera &camera) @@ -486,12 +496,48 @@ S32 LLVOCachePartition::cull(LLCamera &camera) LLVector3 region_agent = mRegionp->getOriginAgent(); camera.calcRegionFrustumPlanes(region_agent); - LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion); + mOccludedGroups.clear(); + + LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion, this); culler.traverse(mOctree); + if(!mOccludedGroups.empty()) + { + processOccluders(&camera); + mOccludedGroups.clear(); + } + return 0; } +void LLVOCachePartition::addOccluders(LLviewerOctreeGroup* gp) +{ + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)gp; + + const U32 MIN_WAIT_TIME = 16; //wait 16 frames to issue a new occlusion request + U32 last_issued_time = group->getLastOcclusionIssuedTime(); + if(gFrameCount > last_issued_time && gFrameCount < last_issued_time + MIN_WAIT_TIME) + { + return; + } + + if(group && !group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION)) + { + group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + mOccludedGroups.insert(group); + } +} + +void LLVOCachePartition::processOccluders(LLCamera* camera) +{ + for(std::set<LLOcclusionCullingGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) + { + LLOcclusionCullingGroup* group = *iter; + group->doOcclusion(camera); + group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + } +} + //------------------------------------------------------------------- //LLVOCache //------------------------------------------------------------------- diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index b8a7ccac99fb5ea69bff1e13b4bf7205c00fe209..1aa58528db01b41ddcd053adc698b4ad353c9af4 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -156,8 +156,15 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr void addEntry(LLViewerOctreeEntry* entry); void removeEntry(LLViewerOctreeEntry* entry); /*virtual*/ S32 cull(LLCamera &camera); + void addOccluders(LLviewerOctreeGroup* gp); static LLTrace::MemStatHandle sMemStat; + +private: + void processOccluders(LLCamera* camera); + +private: + std::set<LLOcclusionCullingGroup*> mOccludedGroups; }; //