Attempt to catch octree node manipulation while iterating over said nodes
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user