From 9bffc4bb8201d1fa5127f63b174116a058f6f7e8 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 16 Apr 2020 00:52:55 -0500 Subject: [PATCH] Attempt to squash spatial partition crash. --- indra/newview/lldrawable.cpp | 17 +++++++---------- indra/newview/llspatialpartition.h | 2 +- indra/newview/llvieweroctree.cpp | 28 ++++++++++++++++++++++++++-- indra/newview/llvieweroctree.h | 7 +++++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 19c5d6457..becf850ab 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1596,11 +1596,7 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { - /* - - DON'T DO THIS -- this should happen through octree destruction - - mDrawable->setSpatialGroup(NULL); + mDrawable->setGroup(NULL); if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1608,17 +1604,18 @@ void LLSpatialBridge::cleanupReferences() iter != child_list.end(); iter++) { LLViewerObject* child = *iter; - LLDrawable* drawable = child->mDrawable; + LLDrawable* drawable = child->mDrawable; if (drawable) { - drawable->setSpatialGroup(NULL); + drawable->setGroup(NULL); } } - }*/ + } - LLPointer drawablep = mDrawable; + LLPointer bridgep = mDrawable->getSpatialBridge(); + mDrawable->setSpatialBridge(nullptr); mDrawable = nullptr; - drawablep->setSpatialBridge(nullptr); + bridgep = nullptr; } } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index d46314f4e..c89126432 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -316,7 +316,7 @@ public: void drawObjectBox(LLColor4 col); - LLSpatialPartition* getSpatialPartition() const {return (LLSpatialPartition*)mSpatialPartition;} + LLSpatialPartition* getSpatialPartition() const {return mSpatialPartition;} //LISTENER FUNCTIONS void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face) final override; diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index de4dcc580..d2eca0326 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -846,10 +846,12 @@ public: }; -LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) : +LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLSpatialPartition* part) : LLViewerOctreeGroup(node), mSpatialPartition(part) { + llassert(part); + mSpatialPartition->mGroups.push_back(this); part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -867,12 +869,21 @@ LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctre LLOcclusionCullingGroup::~LLOcclusionCullingGroup() { + if (mSpatialPartition) + { + auto it = std::find_if(mSpatialPartition->mGroups.begin(), mSpatialPartition->mGroups.end(), [this](LLOcclusionCullingGroup* rhs) {return rhs == this; }); + llassert_always(it != mSpatialPartition->mGroups.end()); + if (it != mSpatialPartition->mGroups.end()) + { + mSpatialPartition->mGroups.erase(it); + } + } releaseOcclusionQueryObjectNames(); } BOOL LLOcclusionCullingGroup::needsUpdate() { - return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; + return mSpatialPartition && (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; } BOOL LLOcclusionCullingGroup::isRecentlyVisible() const @@ -1070,6 +1081,10 @@ U32 LLOcclusionCullingGroup::getLastOcclusionIssuedTime() void LLOcclusionCullingGroup::checkOcclusion() { + if (mSpatialPartition == nullptr) + { + return; + } if (LLPipeline::sUseOcclusion > 1) { LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_READBACK); @@ -1170,6 +1185,10 @@ static LLTrace::BlockTimerStatHandle FTM_OCCLUSION_DRAW("Draw"); void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift) { + if (mSpatialPartition == nullptr) + { + return; + } LLGLDisable stencil; if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { @@ -1319,6 +1338,11 @@ LLViewerOctreePartition::LLViewerOctreePartition() : LLViewerOctreePartition::~LLViewerOctreePartition() { + llassert(mGroups.empty()); + for (auto& entry : mGroups) + { + entry->mSpatialPartition = nullptr; + } delete mOctree; mOctree = NULL; } diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index 31a11dfca..b1560f23f 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -44,6 +44,7 @@ class LLViewerOctreeEntryData; class LLViewerOctreeGroup; class LLViewerOctreeEntry; class LLViewerOctreePartition; +class LLSpatialPartition; typedef LLOctreeListener OctreeListener; typedef LLTreeNode TreeNode; @@ -288,7 +289,7 @@ protected: virtual ~LLOcclusionCullingGroup(); public: - LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part); + LLOcclusionCullingGroup(OctreeNode* node, LLSpatialPartition* part); LLOcclusionCullingGroup(const LLOcclusionCullingGroup& rhs) : LLViewerOctreeGroup(rhs) { *this = rhs; @@ -330,7 +331,8 @@ protected: S32 mLODHash; - LLViewerOctreePartition* mSpatialPartition; + friend class LLViewerOctreePartition; + LLSpatialPartition* mSpatialPartition; U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; public: @@ -355,6 +357,7 @@ public: BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) + std::vector mGroups; }; class LLViewerOctreeCull : public OctreeTraveler