From c0ba626c8009b22310b3923e8170e5db2a021253 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 15 Oct 2012 21:34:29 -0600 Subject: For SH-3333: Design and implement a new object cache system on viewer side --- indra/newview/llspatialpartition.cpp | 787 ++++++++++++----------------------- 1 file changed, 272 insertions(+), 515 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5083478392..debb790c58 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -138,94 +138,6 @@ void sg_assert(BOOL expr) #endif } -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) -{ - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) -{ - F32 d = 0.f; - F32 t; - - if ((min-origin).magVecSquared() < r && - (max-origin).magVecSquared() < r) - { - return 2; - } - - for (U32 i = 0; i < 3; i++) - { - if (origin.mV[i] < min.mV[i]) - { - t = min.mV[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max.mV[i]) - { - t = origin.mV[i] - max.mV[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } - } - - return 1; -} - - -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) -{ - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) -{ - F32 d = 0.f; - F32 t; - - LLVector4a origina; - origina.load3(origin.mV); - - LLVector4a v; - v.setSub(min, origina); - - if (v.dot3(v) < r) - { - v.setSub(max, origina); - if (v.dot3(v) < r) - { - return 2; - } - } - - - for (U32 i = 0; i < 3; i++) - { - if (origin.mV[i] < min[i]) - { - t = min[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max[i]) - { - t = origin.mV[i] - max[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } - } - - return 1; -} - - typedef enum { b000 = 0x00, @@ -352,13 +264,17 @@ LLSpatialGroup::~LLSpatialGroup() { llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ + if(isVisible()) + { + mSpatialPartition->mRegionp->clearVisibleGroup(this); + } if (gDebugGL) { gPipeline.checkReferences(this); } - if (isState(DEAD)) + if (hasState(DEAD)) { sZombieGroups--; } @@ -514,7 +430,8 @@ BOOL LLSpatialGroup::isHUDGroup() BOOL LLSpatialGroup::isRecentlyVisible() const { - return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ; + const S32 MIN_VIS_FRAME_RANGE = 2; + return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; } BOOL LLSpatialGroup::isVisible() const @@ -619,7 +536,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) OctreeNode* parent = mOctreeNode->getOctParent(); if (mOctreeNode->isInside(drawablep->getPositionGroup()) && - (mOctreeNode->contains(drawablep) || + (mOctreeNode->contains(drawablep->getEntry()) || (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { @@ -633,15 +550,14 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) } -BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree) +BOOL LLSpatialGroup::addObject(LLDrawable *drawablep) { - if (!from_octree) + if(!drawablep) { - mOctreeNode->insert(drawablep); + return FALSE; } - else { - drawablep->setSpatialGroup(this); + drawablep->setGroup(this); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -664,7 +580,7 @@ void LLSpatialGroup::rebuildGeom() { mSpatialPartition->rebuildGeom(this); - if (isState(LLSpatialGroup::MESH_DIRTY)) + if (hasState(LLSpatialGroup::MESH_DIRTY)) { gPipeline.markMeshDirty(this); } @@ -686,7 +602,7 @@ static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -751,103 +667,6 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) -{ - const OctreeNode* node = mOctreeNode; - - if (node->isEmpty()) - { //don't do anything if there are no objects - if (empty && mOctreeNode->getParent()) - { //only root is allowed to be empty - OCT_ERRS << "Empty leaf found in octree." << llendl; - } - return FALSE; - } - - LLVector4a& newMin = mObjectExtents[0]; - LLVector4a& newMax = mObjectExtents[1]; - - if (isState(OBJECT_DIRTY)) - { //calculate new bounding box - clearState(OBJECT_DIRTY); - - //initialize bounding box to first element - OctreeNode::const_element_iter i = node->getDataBegin(); - LLDrawable* drawablep = *i; - const LLVector4a* minMax = drawablep->getSpatialExtents(); - - newMin = minMax[0]; - newMax = minMax[1]; - - for (++i; i != node->getDataEnd(); ++i) - { - drawablep = *i; - minMax = drawablep->getSpatialExtents(); - - update_min_max(newMin, newMax, minMax[0]); - update_min_max(newMin, newMax, minMax[1]); - - //bin up the object - /*for (U32 i = 0; i < 3; i++) - { - if (minMax[0].mV[i] < newMin.mV[i]) - { - newMin.mV[i] = minMax[0].mV[i]; - } - if (minMax[1].mV[i] > newMax.mV[i]) - { - newMax.mV[i] = minMax[1].mV[i]; - } - }*/ - } - - mObjectBounds[0].setAdd(newMin, newMax); - mObjectBounds[0].mul(0.5f); - mObjectBounds[1].setSub(newMax, newMin); - mObjectBounds[1].mul(0.5f); - } - - if (empty) - { - minOut = newMin; - maxOut = newMax; - } - else - { - minOut.setMin(minOut, newMin); - maxOut.setMax(maxOut, newMax); - } - - return TRUE; -} - -void LLSpatialGroup::unbound() -{ - if (isState(DIRTY)) - { - return; - } - - setState(DIRTY); - - //all the parent nodes need to rebound this child - if (mOctreeNode) - { - OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); - while (parent != NULL) - { - LLSpatialGroup* group = (LLSpatialGroup*) parent->getListener(0); - if (group->isState(DIRTY)) - { - return; - } - - group->setState(DIRTY); - parent = (OctreeNode*) parent->getParent(); - } - } -} - LLSpatialGroup* LLSpatialGroup::getParent() { if (isDead()) @@ -871,17 +690,19 @@ LLSpatialGroup* LLSpatialGroup::getParent() BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { + if(!drawablep) + { + return FALSE; + } + unbound(); if (mOctreeNode && !from_octree) { - if (!mOctreeNode->remove(drawablep)) - { - OCT_ERRS << "Could not remove drawable from spatial group" << llendl; - } + drawablep->setGroup(NULL); } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -928,12 +749,12 @@ void LLSpatialGroup::shift(const LLVector4a &offset) } } -class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetState : public OctreeTraveler { public: U32 mState; LLSpatialSetState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState @@ -941,24 +762,17 @@ class LLSpatialSetStateDiff : public LLSpatialSetState public: LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (!group->isState(mState)) + if (!group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::setState(U32 state) -{ - mState |= state; - - llassert(state <= LLSpatialGroup::STATE_MASK); -} - void LLSpatialGroup::setState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -982,12 +796,12 @@ void LLSpatialGroup::setState(U32 state, S32 mode) } } -class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearState : public OctreeTraveler { public: U32 mState; LLSpatialClearState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState @@ -995,24 +809,17 @@ class LLSpatialClearStateDiff : public LLSpatialClearState public: LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (group->isState(mState)) + if (group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::clearState(U32 state) -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - mState &= ~state; -} - void LLSpatialGroup::clearState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -1036,22 +843,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } -BOOL LLSpatialGroup::isState(U32 state) const -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - return mState & state ? TRUE : FALSE; -} - //===================================== // Occlusion State Set/Clear //===================================== -class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } }; class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState @@ -1059,13 +859,13 @@ class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState public: LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (!group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1110,13 +910,13 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) } } -class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } }; class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState @@ -1124,13 +924,13 @@ class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState public: LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1166,13 +966,11 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLviewerOctreeGroup(node), mObjectBoxSize(1.f), - mState(0), mGeometryBytes(0), mSurfaceArea(0.f), mBuilt(0.f), - mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), @@ -1191,17 +989,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mViewAngle.splat(0.f); mLastUpdateViewAngle.splat(-1.f); - mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = - mObjectExtents[0] = mObjectExtents[1] = mViewAngle; - + sg_assert(mOctreeNode->getListenerCount() == 0); - mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - mBounds[0] = node->getCenter(); - mBounds[1] = node->getSize(); - part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -1235,7 +1027,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) } #if !LL_RELEASE_FOR_DOWNLOAD - if (isState(LLSpatialGroup::OBJECT_DIRTY)) + if (hasState(LLSpatialGroup::OBJECT_DIRTY)) { llerrs << "Spatial group dirty on distance update." << llendl; } @@ -1266,7 +1058,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) dist = eye.getLength3().getF32(); eye.normalize3fast(); - if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) + if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) { if (!group->mSpatialPartition->isBridge()) { @@ -1343,7 +1135,7 @@ BOOL LLSpatialGroup::needsUpdate() BOOL LLSpatialGroup::changeLOD() { - if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { ///a rebuild is going to happen, update distance and LoD return TRUE; } @@ -1371,29 +1163,51 @@ BOOL LLSpatialGroup::changeLOD() return FALSE; } -void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) +void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - addObject(drawablep, FALSE, TRUE); + if(mSpatialPartition->isVOCachePartition()) + { + LLviewerOctreeGroup::handleInsertion(node, entry); + return; + } + + addObject((LLDrawable*)entry->getDrawable()); unbound(); setState(OBJECT_DIRTY); } -void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) +void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - removeObject(drawable, TRUE); - setState(OBJECT_DIRTY); + if(!mSpatialPartition->isVOCachePartition()) + { + removeObject((LLDrawable*)entry->getDrawable(), TRUE); + } + LLviewerOctreeGroup::handleRemoval(node, entry); } void LLSpatialGroup::handleDestruction(const TreeNode* node) { setState(DEAD); - + + if(mSpatialPartition->isVOCachePartition()) + { + LLviewerOctreeGroup::handleDestruction(node); + return; + } + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; - if (drawable->getSpatialGroup() == this) + LLViewerOctreeEntry* entry = *i; + if (entry->getGroup() == this) { - drawable->setSpatialGroup(NULL); + if(entry->hasDrawable()) + { + ((LLDrawable*)entry->getDrawable())->setGroup(NULL); + } + else + { + llerrs << "No Drawable found in the entry." << llendl; + } } } @@ -1415,16 +1229,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) mOctreeNode = NULL; } -void LLSpatialGroup::handleStateChange(const TreeNode* node) -{ - //drop bounding box upon state change - if (mOctreeNode != node) - { - mOctreeNode = (OctreeNode*) node; - } - unbound(); -} - void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { if (child->getListenerCount() == 0) @@ -1441,11 +1245,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c assert_states_valid(this); } -void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) -{ - unbound(); -} - void LLSpatialGroup::destroyGL(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1476,7 +1275,11 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); @@ -1488,69 +1291,6 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } } -BOOL LLSpatialGroup::rebound() -{ - if (!isState(DIRTY)) - { //return TRUE if we're not empty - return TRUE; - } - - if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->rebound(); - - //copy single child's bounding box - mBounds[0] = group->mBounds[0]; - mBounds[1] = group->mBounds[1]; - mExtents[0] = group->mExtents[0]; - mExtents[1] = group->mExtents[1]; - - group->setState(SKIP_FRUSTUM_CHECK); - } - else if (mOctreeNode->isLeaf()) - { //copy object bounding box if this is a leaf - boundObjects(TRUE, mExtents[0], mExtents[1]); - mBounds[0] = mObjectBounds[0]; - mBounds[1] = mObjectBounds[1]; - } - else - { - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - //initialize to first child - newMin = group->mExtents[0]; - newMax = group->mExtents[1]; - - //first, rebound children - for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) - { - group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - const LLVector4a& max = group->mExtents[1]; - const LLVector4a& min = group->mExtents[0]; - - newMax.setMax(newMax, max); - newMin.setMin(newMin, min); - } - - boundObjects(FALSE, newMin, newMax); - - mBounds[0].setAdd(newMin, newMax); - mBounds[0].mul(0.5f); - mBounds[1].setSub(newMax, newMin); - mBounds[1].mul(0.5f); - } - - clearState(DIRTY); - - return TRUE; -} - static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); @@ -1769,8 +1509,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) -: mRenderByGroup(render_by_group), mBridge(NULL) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) +: mRenderByGroup(render_by_group), mBridge(NULL), mRegionp(regionp) { mOcclusionEnabled = TRUE; mDrawableType = 0; @@ -1782,13 +1522,13 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mDepthMask = FALSE; mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; + mVisitedTime = 0; LLVector4a center, size; center.splat(0.f); size.splat(1.f); - mOctree = new LLSpatialGroup::OctreeRoot(center,size, - NULL); + mOctree = new OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } @@ -1799,6 +1539,10 @@ LLSpatialPartition::~LLSpatialPartition() mOctree = NULL; } +BOOL LLSpatialPartition::isVOCachePartition() const +{ + return mPartitionType == LLViewerRegion::PARTITION_VO_CACHE; +} LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { @@ -1806,12 +1550,16 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) //keep drawable from being garbage collected LLPointer ptr = drawablep; - - assert_octree_valid(mOctree); - mOctree->insert(drawablep); - assert_octree_valid(mOctree); + + if(!drawablep->getGroup()) + { + assert_octree_valid(mOctree); + mOctree->insert(drawablep->getEntry()); + assert_octree_valid(mOctree); + } LLSpatialGroup* group = drawablep->getSpatialGroup(); + llassert(group != NULL); if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) { @@ -1829,7 +1577,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); } assert_octree_valid(mOctree); @@ -1881,13 +1629,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL put(drawablep, was_visible); } -class LLSpatialShift : public LLSpatialGroup::OctreeTraveler +class LLSpatialShift : public OctreeTraveler { public: const LLVector4a& mOffset; LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } @@ -1899,17 +1647,17 @@ void LLSpatialPartition::shift(const LLVector4a &offset) shifter.traverse(mOctree); } -class LLOctreeCull : public LLSpatialGroup::OctreeTraveler +class LLOctreeCull : public LLViewerOctreeCull { public: - LLOctreeCull(LLCamera* camera) - : mCamera(camera), mRes(0) { } + LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; group->checkOcclusion(); - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -1919,79 +1667,30 @@ public: return false; } - - virtual void traverse(const LLSpatialGroup::OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (earlyFail(group)) - { - return; - } - if (mRes == 2 || - (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK))) - { //fully in, just add everything - LLSpatialGroup::OctreeTraveler::traverse(n); - } - else - { - mRes = frustumCheck(group); - - if (mRes) - { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); - } - - mRes = 0; - } - } - - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + S32 res = AABBInFrustumNoFarClipGroupBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectGroupExtents(group)); } return res; } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectObjectExtents(group)); } return res; } - virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) - { - if (branch->getElementCount() == 0) //no elements - { - return false; - } - else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box - { - return true; - } - else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum - { - return false; - } - - return true; - } - - virtual void preprocess(LLSpatialGroup* group) - { - - } - - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) { @@ -1999,21 +1698,6 @@ public: } gPipeline.markNotCulled(group, *mCamera); } - - virtual void visit(const LLSpatialGroup::OctreeNode* branch) - { - LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - preprocess(group); - - if (checkObjects(branch, group)) - { - processGroup(group); - } - } - - LLCamera *mCamera; - S32 mRes; }; class LLOctreeCullNoFarClip : public LLOctreeCull @@ -2022,14 +1706,14 @@ public: LLOctreeCullNoFarClip(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumNoFarClipGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); return res; } }; @@ -2040,14 +1724,14 @@ public: LLOctreeCullShadow(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); + return AABBInFrustumObjectBounds(group); } }; @@ -2057,9 +1741,11 @@ public: LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -2069,7 +1755,7 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -2078,10 +1764,10 @@ public: return; } - if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || + if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || mRes == 2) { //don't need to do frustum check - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } else { @@ -2089,31 +1775,35 @@ public: if (mRes) { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } mRes = 0; } } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty()) if (mRes < 2) { - if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) + if (AABBInFrustumObjectBounds(group) > 0) { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + const LLVector4a* exts = group->getObjectExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } else { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mExtents[0]); - update_min_max(mMin, mMax, group->mExtents[1]); + const LLVector4a* exts = group->getExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } @@ -2128,10 +1818,12 @@ public: LLOctreeCullDetectVisible(LLCamera* camera) : LLOctreeCullShadow(camera), mResult(FALSE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + if (mResult || //already found a node, don't check any more - (group->mOctreeNode->getParent() && //never occlusion cull the root node + (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED))) { @@ -2141,9 +1833,9 @@ public: return false; } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - if (group->isVisible()) + if (base_group->isVisible()) { mResult = TRUE; } @@ -2158,17 +1850,21 @@ public: LLOctreeSelect(LLCamera* camera, std::vector* results) : LLOctreeCull(camera), mResults(results) { } - virtual bool earlyFail(LLSpatialGroup* group) { return false; } - virtual void preprocess(LLSpatialGroup* group) { } + virtual bool earlyFail(LLviewerOctreeGroup* group) { return false; } + virtual void preprocess(LLviewerOctreeGroup* group) { } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + OctreeNode* branch = group->getOctreeNode(); - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!drawable->isDead()) { if (drawable->isSpatialBridge()) @@ -2281,17 +1977,21 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); } -class LLOctreeDirty : public LLOctreeTraveler +class LLOctreeDirty : public OctreeTraveler { public: - virtual void visit(const LLOctreeNode* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); @@ -2350,6 +2050,13 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { + bool is_vo_cache_part = (mPartitionType == LLViewerRegion::PARTITION_VO_CACHE); + + if(is_vo_cache_part && mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //no need to visit more than once per frame + } + #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif @@ -2364,18 +2071,18 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result #endif - if (for_select) + if (for_select && !is_vo_cache_part) { LLOctreeSelect selecter(&camera, results); selecter.traverse(mOctree); } - else if (LLPipeline::sShadowRender) + else if (LLPipeline::sShadowRender && !is_vo_cache_part) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } - else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) + else if ((mInfiniteFarClip || !LLPipeline::sUseFarClip) && !is_vo_cache_part) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); @@ -2383,6 +2090,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result } else { + if(is_vo_cache_part) + { + mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); + } + LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); @@ -2402,9 +2114,10 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) LLVector4a fudge; fudge.splat(vel); - const LLVector4a& c = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + const LLVector4a& c = bounds[0]; LLVector4a r; - r.setAdd(group->mBounds[1], fudge); + r.setAdd(bounds[1], fudge); /*if (r.magVecSquared() > 1024.0*1024.0) { @@ -2529,7 +2242,8 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask) } else { - drawBox(group->mBounds[0], group->mBounds[1]); + const LLVector4a* bounds = group->getBounds(); + drawBox(bounds[0], bounds[1]); } } @@ -2593,13 +2307,19 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4f(1,0,0,group->mBuilt); gGL.flush(); glLineWidth(5.f); - drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + + const LLVector4a* bounds = group->getObjectBounds(); + drawBoxOutline(bounds[0], bounds[1]); gGL.flush(); glLineWidth(1.f); gGL.flush(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!group->mSpatialPartition->isBridge()) { gGL.pushMatrix(); @@ -2657,9 +2377,10 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4fv(col.mV); LLVector4a fudge; fudge.splat(0.001f); - LLVector4a size = group->mObjectBounds[1]; - size.mul(1.01f); - size.add(fudge); + + //LLVector4a size = group->mObjectBounds[1]; + //size.mul(1.01f); + //size.add(fudge); //{ // LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2675,7 +2396,9 @@ void renderOctree(LLSpatialGroup* group) //drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); gGL.diffuseColor4f(0,1,1,1); - drawBoxOutline(group->mBounds[0],group->mBounds[1]); + + const LLVector4a* bounds = group->getBounds(); + drawBoxOutline(bounds[0], bounds[1]); //draw bounding box for draw info /*if (group->mSpatialPartition->mRenderByGroup) @@ -3442,9 +3165,13 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) void renderPhysicsShapes(LLSpatialGroup* group) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } LLVOVolume* volume = drawable->getVOVolume(); if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) { @@ -4001,17 +3728,18 @@ void renderAgentTarget(LLVOAvatar* avatar) } } -class LLOctreeRenderNonOccluded : public LLOctreeTraveler +class LLOctreeRenderNonOccluded : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4051,17 +3779,17 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - LLVector4a nodeCenter = group->mBounds[0]; - LLVector4a octCenter = group->mOctreeNode->getCenter(); + LLVector4a nodeCenter = bounds[0]; + LLVector4a octCenter = group->getOctreeNode()->getCenter(); group->rebuildGeom(); group->rebuildMesh(); @@ -4071,15 +3799,20 @@ public: if (!group->isEmpty()) { gGL.diffuseColor3f(0,0,1); - drawBoxOutline(group->mObjectBounds[0], - group->mObjectBounds[1]); + + const LLVector4a* obj_bounds = group->getObjectBounds(); + drawBoxOutline(obj_bounds[0], obj_bounds[1]); } } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { renderBoundingBox(drawable); @@ -4201,17 +3934,18 @@ public: }; -class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler +class LLOctreeRenderPhysicsShapes : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4229,23 +3963,24 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { } }; -class LLOctreePushBBoxVerts : public LLOctreeTraveler +class LLOctreePushBBoxVerts : public OctreeTraveler { public: LLCamera* mCamera; LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1])) { node->accept(this); @@ -4256,19 +3991,23 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } renderBoundingBox(drawable, FALSE); } } @@ -4280,7 +4019,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -class LLOctreeStateCheck : public LLOctreeTraveler +class LLOctreeStateCheck : public OctreeTraveler { public: U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; @@ -4293,7 +4032,7 @@ public: } } - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); @@ -4320,7 +4059,7 @@ public: } - virtual void visit(const LLOctreeNode* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -4332,7 +4071,7 @@ public: } } - if (group->isState(LLSpatialGroup::DIRTY)) + if (group->hasState(LLSpatialGroup::DIRTY)) { assert_parent_state(group, LLSpatialGroup::DIRTY); } @@ -4343,7 +4082,7 @@ public: LLSpatialGroup* parent = group->getParent(); while (parent) { - if (!parent->isState(state)) + if (!parent->hasState(state)) { llerrs << "Spatial group failed parent state check." << llendl; } @@ -4458,7 +4197,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) return TRUE; } -class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public OctreeTraveler { public: LLVector3 mStart; @@ -4485,21 +4224,21 @@ public: { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { check(*i); } } - virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) + virtual LLDrawable* check(const OctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { - const LLSpatialGroup::OctreeNode* child = node->getChild(i); + const OctreeNode* child = node->getChild(i); LLVector3 res; LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); @@ -4507,8 +4246,9 @@ public: LLVector4a size; LLVector4a center; - size = group->mBounds[1]; - center = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + size = bounds[1]; + center = bounds[0]; LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4535,8 +4275,9 @@ public: return mHit; } - virtual bool check(LLDrawable* drawable) + virtual bool check(LLViewerOctreeEntry* entry) { + LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4922,5 +4663,21 @@ void LLCullResult::assertDrawMapsEmpty() } } +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp) +{ + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; +} + +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); + llassert(!entry->getGroup()); +} -- cgit v1.2.3 From a52d203a4f1d2988e8ffba16258f3f132f22f56d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 17 Oct 2012 20:00:07 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system started conversion of llviewerassetstats removed old, dead LLViewerStats code made units tracing require units declaration clean up of units handling --- indra/newview/llspatialpartition.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5083478392..c4c9b0bd4c 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1580,7 +1580,7 @@ void LLSpatialGroup::checkOcclusion() LLFastTimer t(FTM_OCCLUSION_WAIT); while (!available && max_loop-- > 0) { - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); //do some usefu work while we wait LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread @@ -2574,7 +2574,7 @@ void renderOctree(LLSpatialGroup* group) LLVector4 col; if (group->mBuilt > 0.f) { - group->mBuilt -= 2.f * gFrameIntervalSeconds; + group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); if (group->mBufferUsage == GL_STATIC_DRAW_ARB) { col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); -- cgit v1.2.3 From 5ae116f89b8459963ccb6ae9125d94ffaa79025e Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 31 Oct 2012 17:05:53 -0600 Subject: for SH-3471: create a simplified version of octree for object cache entries. --- indra/newview/llspatialpartition.cpp | 108 +++++++++-------------------------- 1 file changed, 27 insertions(+), 81 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index debb790c58..e9ece331d1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -264,11 +264,7 @@ LLSpatialGroup::~LLSpatialGroup() { llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ - if(isVisible()) - { - mSpatialPartition->mRegionp->clearVisibleGroup(this); - } - + if (gDebugGL) { gPipeline.checkReferences(this); @@ -434,16 +430,6 @@ BOOL LLSpatialGroup::isRecentlyVisible() const return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; } -BOOL LLSpatialGroup::isVisible() const -{ - return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; -} - -void LLSpatialGroup::setVisible() -{ - mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame(); -} - void LLSpatialGroup::validate() { ll_assert_aligned(this,64); @@ -1165,12 +1151,6 @@ BOOL LLSpatialGroup::changeLOD() void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - if(mSpatialPartition->isVOCachePartition()) - { - LLviewerOctreeGroup::handleInsertion(node, entry); - return; - } - addObject((LLDrawable*)entry->getDrawable()); unbound(); setState(OBJECT_DIRTY); @@ -1178,10 +1158,7 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - if(!mSpatialPartition->isVOCachePartition()) - { - removeObject((LLDrawable*)entry->getDrawable(), TRUE); - } + removeObject((LLDrawable*)entry->getDrawable(), TRUE); LLviewerOctreeGroup::handleRemoval(node, entry); } @@ -1189,12 +1166,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) { setState(DEAD); - if(mSpatialPartition->isVOCachePartition()) - { - LLviewerOctreeGroup::handleDestruction(node); - return; - } - for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLViewerOctreeEntry* entry = *i; @@ -1510,8 +1481,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) -: mRenderByGroup(render_by_group), mBridge(NULL), mRegionp(regionp) +: mRenderByGroup(render_by_group), mBridge(NULL) { + mRegionp = regionp; mOcclusionEnabled = TRUE; mDrawableType = 0; mPartitionType = LLViewerRegion::PARTITION_NONE; @@ -1521,27 +1493,14 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - mInfiniteFarClip = FALSE; - mVisitedTime = 0; - - LLVector4a center, size; - center.splat(0.f); - size.splat(1.f); + mInfiniteFarClip = FALSE; - mOctree = new OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } LLSpatialPartition::~LLSpatialPartition() -{ - delete mOctree; - mOctree = NULL; -} - -BOOL LLSpatialPartition::isVOCachePartition() const -{ - return mPartitionType == LLViewerRegion::PARTITION_VO_CACHE; +{ } LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) @@ -2050,12 +2009,7 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { - bool is_vo_cache_part = (mPartitionType == LLViewerRegion::PARTITION_VO_CACHE); - - if(is_vo_cache_part && mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) - { - return 0; //no need to visit more than once per frame - } + llassert(results != NULL && for_select); #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); @@ -2070,19 +2024,34 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif + LLOctreeSelect selecter(&camera, results); + selecter.traverse(mOctree); - if (for_select && !is_vo_cache_part) + return 0; +} + +S32 LLSpatialPartition::cull(LLCamera &camera) +{ +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); +#endif { - LLOctreeSelect selecter(&camera, results); - selecter.traverse(mOctree); + LLFastTimer ftm(FTM_CULL_REBOUND); + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); } - else if (LLPipeline::sShadowRender && !is_vo_cache_part) + +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); +#endif + + if (LLPipeline::sShadowRender) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } - else if ((mInfiniteFarClip || !LLPipeline::sUseFarClip) && !is_vo_cache_part) + else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); @@ -2090,11 +2059,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result } else { - if(is_vo_cache_part) - { - mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); - } - LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); @@ -4663,21 +4627,3 @@ void LLCullResult::assertDrawMapsEmpty() } } -LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp) -{ - mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; -} - -void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) -{ - llassert(entry->hasVOCacheEntry()); - - mOctree->insert(entry); -} - -void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) -{ - entry->getVOCacheEntry()->setGroup(NULL); - - llassert(!entry->getGroup()); -} -- cgit v1.2.3 From 21409a3aaaef71102195d65fc35cebdb5d941a26 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 30 Nov 2012 22:50:06 -0700 Subject: for SH-3350 and SH-3353: Report frame-to-frame visual deltas as an LLStat --- indra/newview/llspatialpartition.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index e9ece331d1..b7694074a5 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -126,6 +126,16 @@ protected: static LLOcclusionQueryPool sQueryPool; +GLuint get_new_occlusion_query_object_name() +{ + return sQueryPool.allocate(); +} + +void release_occlusion_query_object_name(GLuint name) +{ + sQueryPool.release(name); +} + //static counter for frame to switch LOD on void sg_assert(BOOL expr) @@ -283,7 +293,7 @@ LLSpatialGroup::~LLSpatialGroup() { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); } } } @@ -879,7 +889,7 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -890,7 +900,7 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) mOcclusionState[LLViewerCamera::sCurCameraID] |= state; if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } } @@ -1237,7 +1247,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -1318,7 +1328,7 @@ void LLSpatialGroup::checkOcclusion() } else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { //delete the query to avoid holding onto hundreds of pending queries - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } @@ -1390,7 +1400,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) { LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = get_new_occlusion_query_object_name(); } // Depth clamp all water to avoid it being culled as a result of being -- cgit v1.2.3 From 7cc37d949e9319a5b60641ff8453a0fed763d817 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 9 Jan 2013 22:43:10 -0700 Subject: fix the merge errors from the changeset 3eadda9666cf --- indra/newview/llspatialpartition.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index bcafe2e008..0e2109c4af 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1549,8 +1549,6 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) drawablep->setGroup(NULL); } - drawablep->setSpatialGroup(NULL); - assert_octree_valid(mOctree); return TRUE; -- cgit v1.2.3 From 16616ae48d86da75b3809fa6be6c846a9d420603 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 23 May 2013 18:25:21 -0600 Subject: for SH-4145: Interesting: Implement occlusion culling for object cache --- indra/newview/llspatialpartition.cpp | 678 ++--------------------------------- 1 file changed, 34 insertions(+), 644 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 53f5658815..3f426d8f8a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,32 +51,16 @@ #include "llvoavatar.h" #include "llvolumemgr.h" #include "lltextureatlas.h" -#include "llglslshader.h" #include "llviewershadermgr.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); -const F32 SG_OCCLUSION_FUDGE = 0.25f; -#define SG_DISCARD_TOLERANCE 0.01f - -#if LL_OCTREE_PARANOIA_CHECK -#define assert_octree_valid(x) x->validate() -#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() -#else -#define assert_octree_valid(x) -#define assert_states_valid(x) -#endif - extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; -#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 - -std::set LLSpatialGroup::sPendingQueries; - U32 gOctreeMaxCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -84,57 +68,6 @@ BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; -class LLOcclusionQueryPool : public LLGLNamePool -{ -public: - LLOcclusionQueryPool() - { - mCurQuery = 1; - } - -protected: - - std::list mAvailableName; - GLuint mCurQuery; - - virtual GLuint allocateName() - { - GLuint ret = 0; - - if (!mAvailableName.empty()) - { - ret = mAvailableName.front(); - mAvailableName.pop_front(); - } - else - { - ret = mCurQuery++; - } - - return ret; - } - - virtual void releaseName(GLuint name) - { -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - LLSpatialGroup::sPendingQueries.erase(name); -#endif - llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); - mAvailableName.push_back(name); - } -}; - -static LLOcclusionQueryPool sQueryPool; - -GLuint get_new_occlusion_query_object_name() -{ - return sQueryPool.allocate(); -} - -void release_occlusion_query_object_name(GLuint name) -{ - sQueryPool.release(name); -} //static counter for frame to switch LOD on @@ -148,97 +81,6 @@ void sg_assert(BOOL expr) #endif } -typedef enum -{ - b000 = 0x00, - b001 = 0x01, - b010 = 0x02, - b011 = 0x03, - b100 = 0x04, - b101 = 0x05, - b110 = 0x06, - b111 = 0x07, -} eLoveTheBits; - -//contact Runitai Linden for a copy of the SL object used to write this table -//basically, you give the table a bitmask of the look-at vector to a node and it -//gives you a triangle fan index array -static U16 sOcclusionIndices[] = -{ - //000 - b111, b110, b010, b011, b001, b101, b100, b110, - //001 - b011, b010, b000, b001, b101, b111, b110, b010, - //010 - b101, b100, b110, b111, b011, b001, b000, b100, - //011 - b001, b000, b100, b101, b111, b011, b010, b000, - //100 - b110, b000, b010, b011, b111, b101, b100, b000, - //101 - b010, b100, b000, b001, b011, b111, b110, b100, - //110 - b100, b010, b110, b111, b101, b001, b000, b010, - //111 - b000, b110, b100, b101, b001, b011, b010, b110, -}; - -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return cypher*8; -} - -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return (U8*) (sOcclusionIndices+cypher*8); -} - -//create a vertex buffer for efficiently rendering cubes -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) -{ - LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); - - ret->allocateBuffer(8, 64, true); - - LLStrider pos; - LLStrider idx; - - ret->getVertexStrider(pos); - ret->getIndexStrider(idx); - - pos[0] = LLVector3(-1,-1,-1); - pos[1] = LLVector3(-1,-1, 1); - pos[2] = LLVector3(-1, 1,-1); - pos[3] = LLVector3(-1, 1, 1); - pos[4] = LLVector3( 1,-1,-1); - pos[5] = LLVector3( 1,-1, 1); - pos[6] = LLVector3( 1, 1,-1); - pos[7] = LLVector3( 1, 1, 1); - - for (U32 i = 0; i < 64; i++) - { - idx[i] = sOcclusionIndices[i]; - } - - ret->flush(); - - return ret; -} - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); - //returns: // 0 if sphere and AABB are not intersecting // 1 if they are @@ -285,18 +127,7 @@ LLSpatialGroup::~LLSpatialGroup() sZombieGroups--; } - sNodeCount--; - - if (gGLManager.mHasOcclusionQuery) - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) - { - if (mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - } - } - } + sNodeCount--; clearDrawMap(); clearAtlasList() ; @@ -431,7 +262,7 @@ void LLSpatialGroup::clearDrawMap() BOOL LLSpatialGroup::isHUDGroup() { - return mSpatialPartition && mSpatialPartition->isHUDPartition() ; + return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; } BOOL LLSpatialGroup::isRecentlyVisible() const @@ -461,7 +292,7 @@ void LLSpatialGroup::validate() sg_assert(drawable->getSpatialGroup() == this); if (drawable->getSpatialBridge()) { - sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); + sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge()); } /*if (drawable->isSpatialBridge()) @@ -501,14 +332,6 @@ void LLSpatialGroup::validate() #endif } -void LLSpatialGroup::checkStates() -{ -#if LL_OCTREE_PARANOIA_CHECK - //LLOctreeStateCheck checker; - //checker.traverse(mOctreeNode); -#endif -} - void LLSpatialGroup::validateDrawMap() { #if LL_OCTREE_PARANOIA_CHECK @@ -574,7 +397,7 @@ void LLSpatialGroup::rebuildGeom() { if (!isDead()) { - mSpatialPartition->rebuildGeom(this); + getSpatialPartition()->rebuildGeom(this); if (hasState(LLSpatialGroup::MESH_DIRTY)) { @@ -587,7 +410,7 @@ void LLSpatialGroup::rebuildMesh() { if (!isDead()) { - mSpatialPartition->rebuildMesh(this); + getSpatialPartition()->rebuildMesh(this); } } @@ -665,23 +488,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) LLSpatialGroup* LLSpatialGroup::getParent() { - if (isDead()) - { - return NULL; - } - - if(!mOctreeNode) - { - return NULL; - } - OctreeNode* parent = mOctreeNode->getOctParent(); - - if (parent) - { - return (LLSpatialGroup*) parent->getListener(0); - } - - return NULL; + return (LLSpatialGroup*)LLviewerOctreeGroup::getParent(); } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) @@ -735,10 +542,10 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - if (!mSpatialPartition->mRenderByGroup && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) + if (!getSpatialPartition()->mRenderByGroup && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -839,135 +646,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } -//===================================== -// Occlusion State Set/Clear -//===================================== -class LLSpatialSetOcclusionState : public OctreeTraveler -{ -public: - U32 mState; - LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } -}; - -class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState -{ -public: - LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (!group->isOcclusionState(mState)) - { - OctreeTraveler::traverse(n); - } - } -}; - - -void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialSetOcclusionStateDiff setter(state); - setter.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialSetOcclusionState setter(state); - setter.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] |= state; - - if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] |= state; - if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - } -} - -class LLSpatialClearOcclusionState : public OctreeTraveler -{ -public: - U32 mState; - - LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } -}; - -class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState -{ -public: - LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (group->isOcclusionState(mState)) - { - OctreeTraveler::traverse(n); - } - } -}; - -void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialClearOcclusionStateDiff clearer(state); - clearer.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialClearOcclusionState clearer(state); - clearer.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] &= ~state; - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; - } -} //====================================== // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLviewerOctreeGroup(node), +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part), mObjectBoxSize(1.f), mGeometryBytes(0), mSurfaceArea(0.f), - mBuilt(0.f), - mSpatialPartition(part), + mBuilt(0.f), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), mDistance(0.f), @@ -990,21 +677,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLv setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; - mLODHash = part->mLODSeed; - - OctreeNode* oct_parent = node->getOctParent(); - - LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL; - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionQuery[i] = 0; - mOcclusionIssued[i] = 0; - mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; - mVisible[i] = 0; - } - mRadius = 1; mPixelArea = 1024.f; } @@ -1030,10 +702,10 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #endif if (!isEmpty()) { - mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : + mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : (F32) mOctreeNode->getSize().getLength3().getF32(); - mDistance = mSpatialPartition->calcDistance(this, camera); - mPixelArea = mSpatialPartition->calcPixelArea(this, camera); + mDistance = getSpatialPartition()->calcDistance(this, camera); + mPixelArea = getSpatialPartition()->calcPixelArea(this, camera); } } @@ -1056,7 +728,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) { - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { LLVector4a view_angle = eye; @@ -1124,11 +796,6 @@ F32 LLSpatialGroup::getUpdateUrgency() const } } -BOOL LLSpatialGroup::needsUpdate() -{ - return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; -} - BOOL LLSpatialGroup::changeLOD() { if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) @@ -1136,11 +803,11 @@ BOOL LLSpatialGroup::changeLOD() return TRUE; } - if (mSpatialPartition->mSlopRatio > 0.f) + if (getSpatialPartition()->mSlopRatio > 0.f) { F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); - if (fabsf(ratio) >= mSpatialPartition->mSlopRatio) + if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) { return TRUE; } @@ -1193,7 +860,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) } //clean up avatar attachment stats - LLSpatialBridge* bridge = mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = getSpatialPartition()->asBridge(); if (bridge) { if (bridge->mAvatar.notNull()) @@ -1214,7 +881,7 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c { if (child->getListenerCount() == 0) { - new LLSpatialGroup(child, mSpatialPartition); + new LLSpatialGroup(child, getSpatialPartition()); } else { @@ -1243,14 +910,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) if (!keep_occlusion) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - if (mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } + releaseOcclusionQueryObjectNames(); } @@ -1272,233 +932,13 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } } -static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); - -void LLSpatialGroup::checkOcclusion() -{ - if (LLPipeline::sUseOcclusion > 1) - { - LLFastTimer t(FTM_OCCLUSION_READBACK); - LLSpatialGroup* parent = getParent(); - if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //if the parent has been marked as occluded, the child is implicitly occluded - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - else if (isOcclusionState(QUERY_PENDING)) - { //otherwise, if a query is pending, read it back - - GLuint available = 0; - if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - - static LLCachedControl wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); - - if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) - { //query was issued last frame, wait until it's available - S32 max_loop = 1024; - LLFastTimer t(FTM_OCCLUSION_WAIT); - while (!available && max_loop-- > 0) - { - F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); - //do some usefu work while we wait - LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - } - } - } - else - { - available = 1; - } - - if (available) - { //result is available, read it back, otherwise wait until next frame - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - } - else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { //delete the query to avoid holding onto hundreds of pending queries - release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } - - if (res > 0) - { - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - assert_states_valid(this); - - setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - - assert_states_valid(this); - } - - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - } - else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //check occlusion has been issued for occluded node that has not had a query issued - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - } -} - -static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); -static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); - - - -void LLSpatialGroup::doOcclusion(LLCamera* camera) -{ - if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) - { - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension - if (earlyFail(camera, this)) - { - LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); - setOcclusionState(LLSpatialGroup::DISCARD_QUERY); - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) - { - { //no query pending, or previous query to be discarded - LLFastTimer t(FTM_RENDER_OCCLUSION); - - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = get_new_occlusion_query_object_name(); - } - - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); - -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif - -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - - { - LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); - - //store which frame this query was issued on - mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - - { - LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); - glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader); - - shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); - shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, - mBounds[1][1]+SG_OCCLUSION_FUDGE, - mBounds[1][2]+SG_OCCLUSION_FUDGE); - - if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) - { - LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); - - LLGLSquashToFarClip squash(glh_get_current_projection(), 1); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - else - { - LLFastTimer t(FTM_OCCLUSION_DRAW); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - - - { - LLFastTimer t(FTM_OCCLUSION_END_QUERY); - glEndQueryARB(mode); - } - } - } - - { - LLFastTimer t(FTM_SET_OCCLUSION_STATE); - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); - } - } - } - } -} - //============================================== LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) : mRenderByGroup(render_by_group), mBridge(NULL) { - mRegionp = regionp; - mOcclusionEnabled = TRUE; - mDrawableType = 0; - mPartitionType = LLViewerRegion::PARTITION_NONE; - mLODSeed = 0; - mLODPeriod = 1; + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_NONE; mVertexDataMask = data_mask; mBufferUsage = buffer_usage; mDepthMask = FALSE; @@ -1566,11 +1006,11 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL BOOL was_visible = curp ? curp->isVisible() : FALSE; - if (curp && curp->mSpatialPartition != this) + if (curp && curp->getSpatialPartition() != this) { //keep drawable from being garbage collected LLPointer ptr = drawablep; - if (curp->mSpatialPartition->remove(drawablep, curp)) + if (curp->getSpatialPartition()->remove(drawablep, curp)) { put(drawablep, was_visible); return; @@ -1961,7 +1401,7 @@ public: { continue; } - if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) + if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); } @@ -1985,11 +1425,6 @@ void LLSpatialPartition::resetVertexBuffers() dirty.traverse(mOctree); } -BOOL LLSpatialPartition::isOcclusionEnabled() -{ - return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; -} - BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LLVector4a visMina, visMaxa; @@ -2075,51 +1510,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera) return 0; } -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) -{ - if (camera->getOrigin().isExactlyZero()) - { - return FALSE; - } - - const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector4a fudge; - fudge.splat(vel); - - const LLVector4a* bounds = group->getBounds(); - const LLVector4a& c = bounds[0]; - LLVector4a r; - r.setAdd(bounds[1], fudge); - - /*if (r.magVecSquared() > 1024.0*1024.0) - { - return TRUE; - }*/ - - LLVector4a e; - e.load3(camera->getOrigin().mV); - - LLVector4a min; - min.setSub(c,r); - LLVector4a max; - max.setAdd(c,r); - - S32 lt = e.lessThan(min).getGatheredBits() & 0x7; - if (lt) - { - return FALSE; - } - - S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; - if (gt) - { - return FALSE; - } - - return TRUE; -} - - void pushVerts(LLDrawInfo* params, U32 mask) { LLRenderPass::applyModelMatrix(*params); @@ -2191,7 +1581,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) void pushBufferVerts(LLSpatialGroup* group, U32 mask) { - if (group->mSpatialPartition->mRenderByGroup) + if (group->getSpatialPartition()->mRenderByGroup) { if (!group->mDrawMap.empty()) { @@ -2292,7 +1682,7 @@ void renderOctree(LLSpatialGroup* group) { continue; } - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -2324,7 +1714,7 @@ void renderOctree(LLSpatialGroup* group) } } - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.popMatrix(); } @@ -2336,7 +1726,7 @@ void renderOctree(LLSpatialGroup* group) else { if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty() - && group->mSpatialPartition->mRenderByGroup) + && group->getSpatialPartition()->mRenderByGroup) { col.setVec(0.8f, 0.4f, 0.1f, 0.1f); } @@ -2373,7 +1763,7 @@ void renderOctree(LLSpatialGroup* group) drawBoxOutline(bounds[0], bounds[1]); //draw bounding box for draw info - /*if (group->mSpatialPartition->mRenderByGroup) + /*if (group->getSpatialPartition()->mRenderByGroup) { gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f); for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3147,7 +2537,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLVOVolume* volume = drawable->getVOVolume(); if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) { - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -4225,9 +3615,9 @@ public: LLVector3 local_start = mStart; LLVector3 local_end = mEnd; - if (group->mSpatialPartition->isBridge()) + if (group->getSpatialPartition()->isBridge()) { - LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); + LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix(); local_matrix.invert(); local_start = mStart * local_matrix; -- cgit v1.2.3 From b38170e6817b3f69274d9b5953584a1278a17ca2 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 19 Jun 2013 11:45:44 -0600 Subject: fix for SH-4245: Interesting: crash in LLSpatialGroup::handleDestruction --- indra/newview/llspatialpartition.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 45130efeb9..b9d4c016c2 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -841,11 +841,16 @@ void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* en void LLSpatialGroup::handleDestruction(const TreeNode* node) { + if(isDead()) + { + return; + } setState(DEAD); - for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) + for (element_iter i = getDataBegin(); getElementCount() > 0 && i != getDataEnd();) { LLViewerOctreeEntry* entry = *i; + if (entry->getGroup() == this) { if(entry->hasDrawable()) @@ -853,10 +858,14 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) ((LLDrawable*)entry->getDrawable())->setGroup(NULL); } else - { + { llerrs << "No Drawable found in the entry." << llendl; } } + else + { + ++i; + } } //clean up avatar attachment stats -- cgit v1.2.3 From 576b9339977f50edb11a799d7a274610263f9fdc Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 5 Aug 2013 14:48:26 -0600 Subject: fix for SH-4397: Object cache occlusion culling results are not always correct --- indra/newview/llspatialpartition.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index ad659baa9e..a5045e6a4c 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -265,12 +265,6 @@ BOOL LLSpatialGroup::isHUDGroup() return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; } -BOOL LLSpatialGroup::isRecentlyVisible() const -{ - const S32 MIN_VIS_FRAME_RANGE = 2; - return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; -} - void LLSpatialGroup::validate() { ll_assert_aligned(this,64); -- cgit v1.2.3 From a2c7b0485576c6bb92f6d0eddc762f5e37d5caac Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 7 Aug 2013 22:53:27 -0600 Subject: more fix for SH-4397: Object cache occlusion culling results are not always correct --- indra/newview/llspatialpartition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a5045e6a4c..a1b7bfe72a 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1476,7 +1476,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result return 0; } -S32 LLSpatialPartition::cull(LLCamera &camera) +S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) { #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); -- cgit v1.2.3 From e340009fc59d59e59b2e8d903a884acb76b178eb Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 9 Aug 2013 17:11:19 -0700 Subject: second phase summer cleaning replace llinfos, lldebugs, etc with new LL_INFOS(), LL_DEBUGS(), etc. --- indra/newview/llspatialpartition.cpp | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index ad659baa9e..f3b0108359 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -76,7 +76,7 @@ void sg_assert(BOOL expr) #if LL_OCTREE_PARANOIA_CHECK if (!expr) { - llerrs << "Octree invalid!" << llendl; + LL_ERRS() << "Octree invalid!" << LL_ENDL; } #endif } @@ -114,7 +114,7 @@ LLSpatialGroup::~LLSpatialGroup() { /*if (sNoDelete) { - llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; + LL_ERRS() << "Illegal deletion of LLSpatialGroup!" << LL_ENDL; }*/ if (gDebugGL) @@ -300,7 +300,7 @@ void LLSpatialGroup::validate() LLSpatialPartition* part = drawable->asPartition(); if (!part) { - llerrs << "Drawable reports it is a spatial bridge but not a partition." << llendl; + LL_ERRS() << "Drawable reports it is a spatial bridge but not a partition." << LL_ENDL; } LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); group->validate(); @@ -685,7 +685,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { - llwarns << "Attempted to update distance for camera other than world camera!" << llendl; + LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL; return; } @@ -697,7 +697,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #if !LL_RELEASE_FOR_DOWNLOAD if (hasState(LLSpatialGroup::OBJECT_DIRTY)) { - llerrs << "Spatial group dirty on distance update." << llendl; + LL_ERRS() << "Spatial group dirty on distance update." << LL_ENDL; } #endif if (!isEmpty()) @@ -859,7 +859,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) } else { - llerrs << "No Drawable found in the entry." << llendl; + LL_ERRS() << "No Drawable found in the entry." << LL_ENDL; } } else @@ -894,7 +894,7 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c } else { - OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl; + OCT_ERRS << "LLSpatialGroup redundancy detected." << LL_ENDL; } unbound(); @@ -991,7 +991,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) { if (!curp->removeObject(drawablep)) { - OCT_ERRS << "Failed to remove drawable from octree!" << llendl; + OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL; } else { @@ -1009,7 +1009,7 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) if (!drawablep) { - OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl; + OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << LL_ENDL; return; } @@ -1026,7 +1026,7 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL } else { - OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << llendl; + OCT_ERRS << "Drawable lost between spatial partitions on outbound transition." << LL_ENDL; } } @@ -1041,7 +1041,7 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL LLPointer ptr = drawablep; if (curp && !remove(drawablep, curp)) { - OCT_ERRS << "Move couldn't find existing spatial group!" << llendl; + OCT_ERRS << "Move couldn't find existing spatial group!" << LL_ENDL; } put(drawablep, was_visible); @@ -1973,7 +1973,7 @@ void renderUpdateType(LLDrawable* drawablep) gGL.diffuseColor4f(0,0,1,0.5f); break; default: - llwarns << "Unknown update_type " << vobj->getLastUpdateType() << llendl; + LL_WARNS() << "Unknown update_type " << vobj->getLastUpdateType() << LL_ENDL; break; }; S32 num_faces = drawablep->getNumFaces(); @@ -2620,7 +2620,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) } else { - llerrs << "Unhandled type" << llendl; + LL_ERRS() << "Unhandled type" << LL_ENDL; } gGL.popMatrix(); @@ -3368,11 +3368,11 @@ public: { if (facep->mDrawInfo->mTextureList.size() <= index) { - llerrs << "Face texture index out of bounds." << llendl; + LL_ERRS() << "Face texture index out of bounds." << LL_ENDL; } else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) { - llerrs << "Face texture index incorrect." << llendl; + LL_ERRS() << "Face texture index incorrect." << LL_ENDL; } } } @@ -3581,7 +3581,7 @@ public: { if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i])) { - llerrs << "Spatial group failed inherited mask test." << llendl; + LL_ERRS() << "Spatial group failed inherited mask test." << LL_ENDL; } } @@ -3598,7 +3598,7 @@ public: { if (!parent->hasState(state)) { - llerrs << "Spatial group failed parent state check." << llendl; + LL_ERRS() << "Spatial group failed parent state check." << LL_ENDL; } parent = parent->getParent(); } @@ -3927,7 +3927,7 @@ LLDrawInfo::~LLDrawInfo() { /*if (LLSpatialGroup::sNoDelete) { - llerrs << "LLDrawInfo deleted illegally!" << llendl; + LL_ERRS() << "LLDrawInfo deleted illegally!" << LL_ENDL; }*/ if (mFace) @@ -4205,7 +4205,7 @@ void LLCullResult::assertDrawMapsEmpty() { if (mRenderMapSize[i] != 0) { - llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; + LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!" << LL_ENDL; } } } -- cgit v1.2.3 From f713fe492f8b86a0743e0a553d62f06ff62500bb Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 30 Aug 2013 11:02:15 -0600 Subject: fix for SH-4295: Interesting: Teleporting to previous location leave some objects invisible. --- indra/newview/llspatialpartition.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 725afb9014..c7cd0919ec 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -68,6 +68,7 @@ BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; +BOOL LLSpatialPartition::sTeleportRequested = FALSE; //static counter for frame to switch LOD on @@ -900,7 +901,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); - if (!keep_occlusion) + if (!keep_occlusion && !LLSpatialPartition::sTeleportRequested) { //going to need a rebuild gPipeline.markRebuild(this, TRUE); } @@ -1392,6 +1393,8 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) class LLOctreeDirty : public OctreeTraveler { public: + LLOctreeDirty(bool no_rebuild) : mNoRebuild(no_rebuild){} + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -1404,7 +1407,7 @@ public: { continue; } - if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) + if (!mNoRebuild && drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); } @@ -1416,6 +1419,9 @@ public: traverse(bridge->mOctree); } } + +private: + BOOL mNoRebuild; }; void LLSpatialPartition::restoreGL() @@ -1424,7 +1430,7 @@ void LLSpatialPartition::restoreGL() void LLSpatialPartition::resetVertexBuffers() { - LLOctreeDirty dirty; + LLOctreeDirty dirty(sTeleportRequested); dirty.traverse(mOctree); } -- cgit v1.2.3 From cbe397ad13665c7bc993e10d8fe1e4a876253378 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Sep 2013 14:04:13 -0700 Subject: changed fast timer over to using macro another attempt to move mem stat into base class --- indra/newview/llspatialpartition.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'indra/newview/llspatialpartition.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 725afb9014..6bd10ecd0d 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -53,8 +53,8 @@ #include "lltextureatlas.h" #include "llviewershadermgr.h" -static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); -static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); +static LLTrace::TimeBlock FTM_FRUSTUM_CULL("Frustum Culling"); +static LLTrace::TimeBlock FTM_CULL_REBOUND("Cull Rebound Partition"); extern bool gShiftFrame; @@ -408,10 +408,10 @@ void LLSpatialGroup::rebuildMesh() } } -static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); -static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry"); -static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB"); -static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry"); +static LLTrace::TimeBlock FTM_REBUILD_VBO("VBO Rebuilt"); +static LLTrace::TimeBlock FTM_ADD_GEOMETRY_COUNT("Add Geometry"); +static LLTrace::TimeBlock FTM_CREATE_VB("Create VB"); +static LLTrace::TimeBlock FTM_GET_GEOMETRY("Get Geometry"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { @@ -426,7 +426,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateViewAngle = group->mViewAngle; } - LLFastTimer ftm(FTM_REBUILD_VBO); + LL_RECORD_BLOCK_TIME(FTM_REBUILD_VBO); group->clearDrawMap(); @@ -435,14 +435,14 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) U32 vertex_count = 0; { - LLFastTimer t(FTM_ADD_GEOMETRY_COUNT); + LL_RECORD_BLOCK_TIME(FTM_ADD_GEOMETRY_COUNT); addGeometryCount(group, vertex_count, index_count); } if (vertex_count > 0 && index_count > 0) { //create vertex buffer containing volume geometry for this node { - LLFastTimer t(FTM_CREATE_VB); + LL_RECORD_BLOCK_TIME(FTM_CREATE_VB); group->mBuilt = 1.f; if (group->mVertexBuffer.isNull() || !group->mVertexBuffer->isWriteable() || @@ -460,7 +460,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) } { - LLFastTimer t(FTM_GET_GEOMETRY); + LL_RECORD_BLOCK_TIME(FTM_GET_GEOMETRY); getGeometry(group); } } @@ -1435,7 +1435,7 @@ BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, visMaxa.load3(visMax.mV); { - LLFastTimer ftm(FTM_CULL_REBOUND); + LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } @@ -1461,7 +1461,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif { - LLFastTimer ftm(FTM_CULL_REBOUND); + LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } @@ -1482,7 +1482,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif { - LLFastTimer ftm(FTM_CULL_REBOUND); + LL_RECORD_BLOCK_TIME(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } @@ -1493,19 +1493,19 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) if (LLPipeline::sShadowRender) { - LLFastTimer ftm(FTM_FRUSTUM_CULL); + LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) { - LLFastTimer ftm(FTM_FRUSTUM_CULL); + LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); culler.traverse(mOctree); } else { - LLFastTimer ftm(FTM_FRUSTUM_CULL); + LL_RECORD_BLOCK_TIME(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); } -- cgit v1.2.3