Attempt to catch octree node manipulation while iterating over said nodes

This commit is contained in:
Shyotl
2012-09-19 15:12:22 -05:00
parent 438c499718
commit 9bb9292a41
7 changed files with 61 additions and 5 deletions

View File

@@ -81,6 +81,33 @@ public:
virtual void traverse(const LLOctreeNode<T>* node);
};
struct OctreeGuard
{
template <typename T>
OctreeGuard(const LLOctreeNode<T>* node)
{mNode = (void*)node;getNodes().push_back(this);}
~OctreeGuard()
{llassert_always(getNodes().back() == this); getNodes().pop_back();}
template <typename T>
static bool checkGuarded(const LLOctreeNode<T>* node)
{
for(std::vector<OctreeGuard*>::const_iterator it=getNodes().begin();it != getNodes().end();++it)
{
if((*it)->mNode == node)
{
OCT_ERRS << "!!! MANIPULATING OCTREE BRANCH DURING ITERATION !!!" << llendl;
return true;
}
}
return false;
}
static std::vector<OctreeGuard*>& getNodes()
{
static std::vector<OctreeGuard*> gNodes;
return gNodes;
}
void* mNode;
};
template <class T>
class LLOctreeNode : public LLTreeNode<T>
{
@@ -246,8 +273,8 @@ public:
U32 getElementCount() const { return mElementCount; }
bool isEmpty() const { return mElementCount == 0; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
//element_list& getData() { return mData; }
//const element_list& getData() const { return mData; }
element_iter getDataBegin() { return mData; }
element_iter getDataEnd() { return mDataEnd; }
const_element_iter getDataBegin() const { return mData; }
@@ -317,6 +344,7 @@ public:
virtual bool insert(T* data)
{
OctreeGuard::checkGuarded(this);
if (data == NULL || data->getBinIndex() != -1)
{
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
@@ -433,7 +461,7 @@ public:
void _remove(T* data, S32 i)
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
OctreeGuard::checkGuarded(this);
mElementCount--;
data->setBinIndex(-1);
@@ -463,6 +491,7 @@ public:
bool remove(T* data)
{
OctreeGuard::checkGuarded(this);
S32 i = data->getBinIndex();
if (i >= 0 && i < (S32)mElementCount)
@@ -508,6 +537,7 @@ public:
void removeByAddress(T* data)
{
OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < mElementCount; ++i)
{
if (mData[i] == data)
@@ -527,6 +557,7 @@ public:
void clearChildren()
{
OctreeGuard::checkGuarded(this);
mChildCount = 0;
U32* foo = (U32*) mChildMap;
@@ -587,6 +618,7 @@ public:
OCT_ERRS <<"Octree node has too many children... why?" << llendl;
}
#endif
OctreeGuard::checkGuarded(this);
mChildMap[child->getOctant()] = mChildCount;
@@ -606,6 +638,8 @@ public:
void removeChild(S32 index, BOOL destroy = FALSE)
{
OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < this->getListenerCount(); i++)
{
oct_listener* listener = getOctListener(i);

View File

@@ -1276,6 +1276,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
setState(DEAD);
{OctreeGuard guard(mOctreeNode);
for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -1284,6 +1285,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
drawable->setSpatialGroup(NULL);
}
}
}
//clean up avatar attachment stats
LLSpatialBridge* bridge = mSpatialPartition->asBridge();
@@ -1363,6 +1365,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)
}
OctreeGuard guard(mOctreeNode);
for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -2065,6 +2068,7 @@ public:
{
LLSpatialGroup::OctreeNode* branch = group->mOctreeNode;
OctreeGuard guard(branch);
for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -2189,6 +2193,7 @@ public:
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
group->destroyGL();
{OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -2197,6 +2202,7 @@ public:
gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);
}
}
}
for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
{
@@ -2502,6 +2508,7 @@ void renderOctree(LLSpatialGroup* group)
gGL.flush();
glLineWidth(1.f);
gGL.flush();
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -3358,6 +3365,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
void renderPhysicsShapes(LLSpatialGroup* group)
{
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -3885,6 +3893,7 @@ public:
}
}
{OctreeGuard guard(branch);
for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -3980,7 +3989,7 @@ public:
}
}
}
}
}}
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
@@ -4070,6 +4079,7 @@ public:
return;
}
OctreeGuard guard(branch);
for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -4293,6 +4303,7 @@ public:
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
{
OctreeGuard guard(branch);
for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
check(*i);
@@ -4303,6 +4314,7 @@ public:
{
node->accept(this);
OctreeGuard guard(node);
for (U32 i = 0; i < node->getChildCount(); i++)
{
const LLSpatialGroup::OctreeNode* child = node->getChild(i);

View File

@@ -332,7 +332,7 @@ public:
void dirtyMesh() { setState(MESH_DIRTY); }
//octree wrappers to make code more readable
element_list& getData() { return mOctreeNode->getData(); }
//element_list& getData() { return mOctreeNode->getData(); }
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }

View File

@@ -645,6 +645,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;

View File

@@ -557,6 +557,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;

View File

@@ -3494,6 +3494,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST);
//get all the faces into a list
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -3900,6 +3901,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!LLPipeline::sDelayVBUpdate)
{
//drawables have been rebuilt, clear rebuild status
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -3940,6 +3942,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
std::set<LLVertexBuffer*> mapped_buffers;
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -4012,6 +4015,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
warningsCount = 1;
}
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -4484,6 +4488,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
//for each drawable
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;

View File

@@ -2820,6 +2820,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
else
{
group->setVisible();
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
markVisible(*i, camera);
@@ -2908,6 +2909,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (!sSkipUpdate && group->changeLOD())
{
OctreeGuard guard(group->mOctreeNode);
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;
@@ -3044,6 +3046,7 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
{
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
OctreeGuard guard((*i)->mOctreeNode);
for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
{
func(*j);