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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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