diff options
author | Xiaohong Bao <bao@lindenlab.com> | 2012-10-31 17:05:53 -0600 |
---|---|---|
committer | Xiaohong Bao <bao@lindenlab.com> | 2012-10-31 17:05:53 -0600 |
commit | 5ae116f89b8459963ccb6ae9125d94ffaa79025e (patch) | |
tree | d9404c72f950d505cad189764bbf3ca07e62c50d /indra | |
parent | e35a220bf7dd47132174c81181d5f59fb0d54c5d (diff) |
for SH-3471: create a simplified version of octree for object cache entries.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 108 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.h | 49 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.cpp | 48 | ||||
-rw-r--r-- | indra/newview/llvieweroctree.h | 39 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 174 | ||||
-rw-r--r-- | indra/newview/llviewerregion.h | 14 | ||||
-rw-r--r-- | indra/newview/llvocache.cpp | 77 | ||||
-rw-r--r-- | indra/newview/llvocache.h | 13 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 20 |
9 files changed, 346 insertions, 196 deletions
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<LLDrawable *>* 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<LLDrawable *>* 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<LLDrawable *>* 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()); -} diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index dd189d751d..079c0f58f0 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,6 +45,7 @@ #define SG_STATE_INHERIT_MASK (OCCLUDED) #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) +class LLViewerOctreePartition; class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; @@ -225,10 +226,7 @@ public: typedef std::map<U32, drawmap_elem_t > draw_map_t; typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t; typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t; - typedef std::map<U32, buffer_texture_map_t> buffer_map_t; - - typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter; - typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list; + typedef std::map<U32, buffer_texture_map_t> buffer_map_t; struct CompareDistanceGreater { @@ -308,9 +306,7 @@ public: BOOL addObject(LLDrawable *drawablep); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group - BOOL isVisible() const; BOOL isRecentlyVisible() const; - void setVisible(); void shift(const LLVector4a &offset); void checkOcclusion(); //read back last occlusion query (if any) void doOcclusion(LLCamera* camera); //issue occlusion query @@ -325,14 +321,7 @@ public: void setState(U32 state) {mState |= state;} void dirtyGeom() { setState(GEOM_DIRTY); } - void dirtyMesh() { setState(MESH_DIRTY); } - - //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } - element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } - element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } - U32 getElementCount() const { return mOctreeNode->getElementCount(); } - bool isEmpty() const { return mOctreeNode->isEmpty(); } + void dirtyMesh() { setState(MESH_DIRTY); } void drawObjectBox(LLColor4 col); @@ -404,8 +393,7 @@ public: U32 mBufferUsage; draw_map_t mDrawMap; - - S32 mVisible[LLViewerCamera::NUM_CAMERAS]; + F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -428,7 +416,7 @@ public: virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; -class LLSpatialPartition: public LLGeometryManager +class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager { public: LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp); @@ -458,7 +446,8 @@ public: virtual void rebuildMesh(LLSpatialGroup* group); BOOL visibleObjectsInFrustum(LLCamera& camera); - S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum + /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum + S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum BOOL isVisible(const LLVector3& v); bool isHUDPartition() ; @@ -473,26 +462,21 @@ public: void resetVertexBuffers(); BOOL isOcclusionEnabled(); BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); - BOOL isVOCachePartition() const; - + public: - OctreeNode* mOctree; LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe // to call asBridge() from the destructor BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; + U32 mDrawableType; const BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); - BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering - U32 mDrawableType; - U32 mPartitionType; - U32 mVisitedTime; - LLViewerRegion* mRegionp; // the region this partition belongs to. + BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering }; // class for creating bridges between spatial partitions @@ -638,19 +622,6 @@ public: LLVoidWaterPartition(LLViewerRegion* regionp); }; -//spatial partition for hole and edge water (implemented in LLVOWater.cpp) -class LLVOCachePartition : public LLSpatialPartition -{ -public: - LLVOCachePartition(LLViewerRegion* regionp); - - void addEntry(LLViewerOctreeEntry* entry); - void removeEntry(LLViewerOctreeEntry* entry); - - virtual void getGeometry(LLSpatialGroup* group) { } - virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } -}; - //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) class LLTerrainPartition : public LLSpatialPartition { diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 05f977036c..143f2a6819 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -26,6 +26,7 @@ #include "llviewerprecompiledheaders.h" #include "llvieweroctree.h" +#include "llviewerregion.h" //----------------------------------------------------------------------------------- //static variables definitions @@ -324,6 +325,10 @@ void LLViewerOctreeEntryData::setVisible() const LLviewerOctreeGroup::~LLviewerOctreeGroup() { + if(LLViewerRegion::sCurRegionp && isVisible()) + { + LLViewerRegion::sCurRegionp->clearVisibleGroup(this); + } } LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) : @@ -482,8 +487,10 @@ void LLviewerOctreeGroup::handleDestruction(const TreeNode* node) if (obj && obj->getGroup() == this) { obj->nullGroup(); + //obj->setGroup(NULL); } } + mOctreeNode = NULL; } //virtual @@ -500,8 +507,17 @@ void LLviewerOctreeGroup::handleStateChange(const TreeNode* node) //virtual void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { - llerrs << "can not access here. It is an abstract class." << llendl; + if (child->getListenerCount() == 0) + { + new LLviewerOctreeGroup(child); + } + else + { + OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl; + } + unbound(); + //((LLviewerOctreeGroup*)child->getListener(0))->unbound(); } @@ -589,7 +605,35 @@ bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4 //virtual BOOL LLviewerOctreeGroup::isVisible() const { - return TRUE; + return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE; +} + +//virtual +BOOL LLviewerOctreeGroup::isRecentlyVisible() const +{ + return FALSE; +} + +void LLviewerOctreeGroup::setVisible() +{ + mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); +} +//----------------------------------------------------------------------------------- +//class LLViewerOctreePartition definitions +//----------------------------------------------------------------------------------- +LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL) +{ + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new OctreeRoot(center,size, NULL); +} + +LLViewerOctreePartition::~LLViewerOctreePartition() +{ + delete mOctree; + mOctree = NULL; } //----------------------------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index c063e96ea5..498ec3e75d 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -37,8 +37,9 @@ #include "llvector4a.h" #include "llquaternion.h" #include "lloctree.h" -#include "llcamera.h" +#include "llviewercamera.h" +class LLViewerRegion; class LLViewerOctreeEntryData; class LLviewerOctreeGroup; class LLViewerOctreeEntry; @@ -181,6 +182,9 @@ public: }; public: + typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter; + typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list; + LLviewerOctreeGroup(OctreeNode* node); LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs) { @@ -203,8 +207,10 @@ public: virtual void unbound(); virtual void rebound(); - virtual BOOL isVisible() const; - virtual BOOL isRecentlyVisible() const = 0; + void setVisible(); + BOOL isVisible() const; + virtual BOOL isRecentlyVisible() const; + bool isEmpty() const { return mOctreeNode->isEmpty(); } U32 getState() {return mState; } bool isDirty() const {return mState & DIRTY;} @@ -228,20 +234,43 @@ public: const LLVector4a* getObjectBounds() const {return mObjectBounds;} const LLVector4a* getObjectExtents() const {return mObjectExtents;} + //octree wrappers to make code more readable + element_list& getData() { return mOctreeNode->getData(); } + element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } + element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + U32 getElementCount() const { return mOctreeNode->getElementCount(); } + private: virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); protected: U32 mState; - OctreeNode* mOctreeNode; - + OctreeNode* mOctreeNode; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node +public: + S32 mVisible[LLViewerCamera::NUM_CAMERAS]; }LL_ALIGN_POSTFIX(16); +class LLViewerOctreePartition +{ +public: + LLViewerOctreePartition(); + virtual ~LLViewerOctreePartition(); + + // Cull on arbitrary frustum + virtual S32 cull(LLCamera &camera) = 0; + +public: + U32 mPartitionType; + OctreeNode* mOctree; + LLViewerRegion* mRegionp; // the region this partition belongs to. +}; + class LLViewerOctreeCull : public OctreeTraveler { public: diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0c0522d32f..1adab15d70 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -86,6 +86,8 @@ const F32 CAP_REQUEST_TIMEOUT = 18; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; +LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; + typedef std::map<std::string, std::string> CapabilityMap; class LLViewerRegionImpl { @@ -139,7 +141,7 @@ public: LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. std::set< LLPointer<LLVOCacheEntry> > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. - std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup + std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible llspatialgroup LLVOCachePartition* mVOCachePartition; // time? @@ -165,7 +167,7 @@ public: LLCapabilityListener mCapabilityListener; //spatial partitions for objects in this region - std::vector<LLSpatialPartition*> mObjectPartition; + std::vector<LLViewerOctreePartition*> mObjectPartition; }; // support for secondlife:///app/region/{REGION} SLapps @@ -345,7 +347,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE - mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE); + mImpl->mVOCachePartition = getVOCachePartition(); } @@ -384,12 +386,12 @@ LLViewerRegion::~LLViewerRegion() delete mParcelOverlay; delete mImpl->mLandp; delete mImpl->mEventPoll; - LLHTTPSender::clearSender(mImpl->mHost); - - saveObjectCache(); + LLHTTPSender::clearSender(mImpl->mHost); std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + saveObjectCache(); + delete mImpl; mImpl = NULL; } @@ -865,13 +867,13 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d entry->setState(LLVOCacheEntry::INACTIVE); } -void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) { - if(mDead || group->isEmpty() || group->isDead()) + if(mDead || group->isEmpty()) { return; } - + group->setVisible(); mImpl->mVisibleGroups.insert(group); } @@ -909,7 +911,7 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) mImpl->mVisibleEntries.insert(entry); } -void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) { if(mDead) { @@ -920,44 +922,18 @@ void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) mImpl->mVisibleGroups.erase(group); } - -BOOL LLViewerRegion::idleUpdate(F32 max_update_time) -{ - LLTimer update_timer; - - // did_update returns TRUE if we did at least one significant update - BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); - if (mParcelOverlay) - { - // Hopefully not a significant time sink... - mParcelOverlay->idleUpdate(); - } - - if(update_timer.getElapsedTimeF32() > max_update_time) - { - return did_update; - } - - //kill invisible objects - std::vector<LLDrawable*> delete_list; - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); - iter != mImpl->mActiveSet.end(); ++iter) - { - if(!(*iter)->isRecentlyVisible()) - { - killObject((*iter), delete_list); - } - } - for(S32 i = 0; i < delete_list.size(); i++) +//return time left +F32 LLViewerRegion::addLinkedSetChildren(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleEntries.empty()) { - gObjectList.killObject(delete_list[i]->getVObj()); + return max_time; } - delete_list.clear(); + LLTimer update_timer; bool timeout = false; - S32 new_object_count = 64; //minimum number of new objects to be added - //add childrens of visible objects to the rendering pipeline + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) { LLVOCacheEntry* entry = *iter; @@ -968,9 +944,9 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { addNewObject(child); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { - timeout = true; + timeout = true; //timeout break; } } @@ -982,7 +958,10 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { mImpl->mDummyEntries.erase(entry); } - + } + + if(!timeout) + { iter = mImpl->mVisibleEntries.erase(iter); } else @@ -990,17 +969,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) break; //timeout } } + if(timeout) { - mImpl->mVisibleGroups.clear(); - return did_update; + return -1.f; } + return max_time - update_timer.getElapsedTimeF32(); //time left +} - //add objects in the visible groups to the rendering pipeline - std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); +F32 LLViewerRegion::addVisibleObjects(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleGroups.empty()) + { + return max_time; + } + + LLTimer update_timer; + bool timeout = false; + + std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); while(group_iter != mImpl->mVisibleGroups.end()) { - LLSpatialGroup* group = *group_iter; + LLviewerOctreeGroup* group = *group_iter; if(!group->getOctreeNode() || group->isEmpty()) { mImpl->mVisibleGroups.erase(group_iter); @@ -1009,7 +999,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } std::vector<LLViewerOctreeEntry*> entry_list; - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { //group data contents could change during creating new objects, so copy all contents first. entry_list.push_back(*i); @@ -1028,7 +1018,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) { addNewObject(vo_entry); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { timeout = true; break; @@ -1044,12 +1034,75 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } mImpl->mVisibleGroups.erase(group); group_iter = mImpl->mVisibleGroups.begin(); + } + + if(timeout) + { + return -1.0f; } - mImpl->mVisibleGroups.clear(); + return max_time - update_timer.getElapsedTimeF32(); +} + +BOOL LLViewerRegion::idleUpdate(F32 max_update_time) +{ + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update + BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); + + if (mParcelOverlay) + { + // Hopefully not a significant time sink... + mParcelOverlay->idleUpdate(); + } + + max_update_time -= update_timer.getElapsedTimeF32(); + if(max_update_time < 0.f) + { + return did_update; + } + + sCurRegionp = this; + + //kill invisible objects + max_update_time = killInvisibleObjects(max_update_time); + + S32 new_object_count = 64; //minimum number of new objects to be added + + //add childrens of visible objects to the rendering pipeline + max_update_time = addLinkedSetChildren(max_update_time, new_object_count); + + //add objects in the visible groups to the rendering pipeline + if(max_update_time > 0.f) + { + addVisibleObjects(max_update_time, new_object_count); + } + + mImpl->mVisibleGroups.clear(); + sCurRegionp = NULL; return did_update; } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ + std::vector<LLDrawable*> delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + + return max_time; +} + void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list) { //kill the object. @@ -2189,9 +2242,18 @@ void LLViewerRegion::logActiveCapabilities() const LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) { - if (type < mImpl->mObjectPartition.size()) + if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) + { + return (LLSpatialPartition*)mImpl->mObjectPartition[type]; + } + return NULL; +} + +LLVOCachePartition* LLViewerRegion::getVOCachePartition() +{ + if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) { - return mImpl->mObjectPartition[type]; + return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; } return NULL; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 17654a8bc7..86d3ee0d8c 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -69,6 +69,8 @@ class LLBBox; class LLSpatialGroup; class LLDrawable; class LLViewerRegionImpl; +class LLviewerOctreeGroup; +class LLVOCachePartition; class LLViewerRegion: public LLCapabilityProvider // implements this interface { @@ -85,7 +87,7 @@ public: PARTITION_GRASS, PARTITION_VOLUME, PARTITION_BRIDGE, - PARTITION_HUD_PARTICLE, + PARTITION_HUD_PARTICLE, PARTITION_VO_CACHE, PARTITION_NONE, NUM_PARTITIONS @@ -218,12 +220,12 @@ public: F32 getWidth() const { return mWidth; } BOOL idleUpdate(F32 max_update_time); - void addVisibleGroup(LLSpatialGroup* group); + void addVisibleGroup(LLviewerOctreeGroup* group); void addVisibleCacheEntry(LLVOCacheEntry* entry); void addActiveCacheEntry(LLVOCacheEntry* entry); void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); void killCacheEntry(U32 local_id); //physically delete the cache entry - void clearVisibleGroup(LLSpatialGroup* group); + void clearVisibleGroup(LLviewerOctreeGroup* group); // Like idleUpdate, but forces everything to complete regardless of // how long it takes. @@ -333,6 +335,7 @@ public: U32 getNumOfActiveCachedObjects() const; LLSpatialPartition* getSpatialPartition(U32 type); + LLVOCachePartition* getVOCachePartition(); bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const; bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; @@ -350,6 +353,10 @@ private: void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry + F32 killInvisibleObjects(F32 max_time); + F32 addLinkedSetChildren(F32 max_time, S32& max_num_objects); + F32 addVisibleObjects(F32 max_time, S32& max_num_objects); + public: struct CompareDistance { @@ -384,6 +391,7 @@ public: LLDynamicArray<U32> mMapAvatars; LLDynamicArray<LLUUID> mMapAvatarIDs; + static LLViewerRegion* sCurRegionp; private: LLViewerRegionImpl * mImpl; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index f389867484..d4938fd216 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -31,6 +31,7 @@ #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "lldrawable.h" +#include "llviewerregion.h" BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { @@ -356,6 +357,82 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const } //------------------------------------------------------------------- +//LLVOCachePartition +//------------------------------------------------------------------- +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) +{ + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mVisitedTime = 0; + + new LLviewerOctreeGroup(mOctree); +} + +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); + + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); + + llassert(!entry->getGroup()); +} + +class LLVOCacheOctreeCull : public LLViewerOctreeCull +{ +public: + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp) : LLViewerOctreeCull(camera), mRegionp(regionp) {} + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipGroupBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectGroupExtents(group)); + } + return res; + } + + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipObjectBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectObjectExtents(group)); + } + return res; + } + + virtual void processGroup(LLviewerOctreeGroup* base_group) + { + mRegionp->addVisibleGroup(base_group); + } + +private: + LLViewerRegion* mRegionp; +}; + +S32 LLVOCachePartition::cull(LLCamera &camera) +{ + if(mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //already visited. + } + mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); + + ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound(); + + LLVOCacheOctreeCull culler(&camera, mRegionp); + culler.traverse(mOctree); + + return 0; +} + +//------------------------------------------------------------------- //LLVOCache //------------------------------------------------------------------- // Format string used to construct filename for the object cache diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 2228e3e43b..675c12a3eb 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -98,6 +98,19 @@ protected: std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set. }; +class LLVOCachePartition : public LLViewerOctreePartition +{ +public: + LLVOCachePartition(LLViewerRegion* regionp); + + void addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + /*virtual*/ S32 cull(LLCamera &camera); + +private: + U32 mVisitedTime; +}; + // //Note: LLVOCache is not thread-safe // diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e06577c512..850714f676 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -86,6 +86,7 @@ #include "llviewerregion.h" // for audio debugging. #include "llviewerwindow.h" // For getSpinAxis #include "llvoavatarself.h" +#include "llvocache.h" #include "llvoground.h" #include "llvosky.h" #include "llvotree.h" @@ -2352,12 +2353,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { part->cull(camera); } - else if(part->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) - { - part->cull(camera); - } } } + + //scan the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->cull(camera); + } } if (bound_shader) @@ -2433,12 +2437,8 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } assertInitialized(); - - if(group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) - { - group->mSpatialPartition->mRegionp->addVisibleGroup(group); - } - else if (!group->mSpatialPartition->mRenderByGroup) + + if (!group->mSpatialPartition->mRenderByGroup) { //render by drawable sCull->pushDrawableGroup(group); } |