Updated spatial partition and octrees to use std::vector. Also, added diagnostic spew to octrees.

This commit is contained in:
Shyotl
2012-11-04 21:48:17 -06:00
parent 71deb8925e
commit 3ec1dbf51c
7 changed files with 231 additions and 336 deletions

View File

@@ -45,6 +45,7 @@
#endif #endif
extern U32 gOctreeMaxCapacity; extern U32 gOctreeMaxCapacity;
extern U32 gOctreeReserveCapacity;
#if LL_DEBUG #if LL_DEBUG
#define LL_OCTREE_PARANOIA_CHECK 0 #define LL_OCTREE_PARANOIA_CHECK 0
#else #else
@@ -55,6 +56,102 @@ extern U32 gOctreeMaxCapacity;
template <class T> class LLOctreeNode; template <class T> class LLOctreeNode;
#include "lltimer.h"
class OctreeStats : public LLSingleton<OctreeStats>
{
public:
OctreeStats() :
mPeriodNodesCreated(0),
mPeriodNodesDestroyed(0),
mPeriodAllocs(0),
mPeriodFrees(0),
mPeriodLargestSize(0),
mTotalNodes(0),
mTotalAllocs(0),
mTotalFrees(0),
mLargestSize(0),
mTotalSize(0)
{
mTotalTimer.reset();
mPeriodTimer.reset();
}
void addNode()
{
++mTotalNodes;
++mPeriodNodesCreated;
}
void removeNode()
{
--mTotalNodes;
++mPeriodNodesDestroyed;
}
void realloc(U32 old_count, U32 new_count)
{
if(new_count >= old_count)
mTotalSize+=new_count-old_count;
else
mTotalSize-=old_count-new_count;
if(mLargestSize < new_count)
mLargestSize = new_count;
if(mPeriodLargestSize < new_count)
mPeriodLargestSize = new_count;
++mTotalAllocs;
++mPeriodAllocs;
}
void free(U32 count)
{
mTotalSize-=count;
++mTotalFrees;
++mPeriodFrees;
}
void dump()
{
llinfos << llformat("Lifetime: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes: %u AccumSize: %llubytes Avg: %lf LargestSize: %u",
mTotalAllocs,
mTotalFrees,
F64(mTotalAllocs)/mTotalTimer.getElapsedTimeF64(),
F64(mTotalFrees)/mTotalTimer.getElapsedTimeF64(),
mTotalNodes,
mTotalSize*sizeof(LLPointer<LLRefCount>),
F64(mTotalSize)/F64(mTotalNodes),
mLargestSize
) << llendl;
llinfos << llformat("Timeslice: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes:(+%u|-%u) LargestSize: %u",
mPeriodAllocs,
mPeriodFrees,
F64(mPeriodAllocs)/mPeriodTimer.getElapsedTimeF64(),
F64(mPeriodFrees)/mPeriodTimer.getElapsedTimeF64(),
mPeriodNodesCreated,
mPeriodNodesDestroyed,
mPeriodLargestSize
) << llendl;
mPeriodNodesCreated=0;
mPeriodNodesDestroyed=0;
mPeriodAllocs=0;
mPeriodFrees=0;
mPeriodLargestSize=0;
mPeriodTimer.reset();
}
private:
//Accumulate per timer update
U32 mPeriodNodesCreated;
U32 mPeriodNodesDestroyed;
U32 mPeriodAllocs;
U32 mPeriodFrees;
U32 mPeriodLargestSize;
LLTimer mPeriodTimer;
//Accumulate through entire app lifetime:
U32 mTotalNodes;
U32 mTotalAllocs;
U32 mTotalFrees;
U32 mLargestSize;
U64 mTotalSize;
LLTimer mTotalTimer;
};
template <class T> template <class T>
class LLOctreeListener: public LLTreeListener<T> class LLOctreeListener: public LLTreeListener<T>
{ {
@@ -115,9 +212,9 @@ public:
typedef LLOctreeTraveler<T> oct_traveler; typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler; typedef LLTreeTraveler<T> tree_traveler;
typedef LLPointer<T>* element_list; typedef std::vector<LLPointer<T> > element_list;
typedef LLPointer<T>* element_iter; typedef typename element_list::iterator element_iter;
typedef const LLPointer<T>* const_element_iter; typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter; typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef LLOctreeNode<T>** child_list; typedef LLOctreeNode<T>** child_list;
typedef LLOctreeNode<T>** child_iter; typedef LLOctreeNode<T>** child_iter;
@@ -143,8 +240,13 @@ public:
: mParent((oct_node*)parent), : mParent((oct_node*)parent),
mOctant(octant) mOctant(octant)
{ {
mData = NULL; OctreeStats::getInstance()->addNode();
mDataEnd = NULL;
if(gOctreeReserveCapacity)
mData.reserve(gOctreeReserveCapacity);
OctreeStats::getInstance()->realloc(0,mData.capacity());
//mData = NULL;
//mDataEnd = NULL;
mCenter = center; mCenter = center;
mSize = size; mSize = size;
@@ -155,24 +257,27 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter); mOctant = ((oct_node*) mParent)->getOctant(mCenter);
} }
mElementCount = 0; //mElementCount = 0;
clearChildren(); clearChildren();
} }
virtual ~LLOctreeNode() virtual ~LLOctreeNode()
{ {
OctreeStats::getInstance()->removeNode();
BaseType::destroyListeners(); BaseType::destroyListeners();
for (U32 i = 0; i < mElementCount; ++i) //for (U32 i = 0; i < mElementCount; ++i)
for (U32 i = 0; i < mData.size(); ++i)
{ {
mData[i]->setBinIndex(-1); mData[i]->setBinIndex(-1);
mData[i] = NULL; mData[i] = NULL;
} }
free(mData); OctreeStats::getInstance()->free(mData.capacity());
mData = NULL; //free(mData);
mDataEnd = NULL; //mData = NULL;
//mDataEnd = NULL;
for (U32 i = 0; i < getChildCount(); i++) for (U32 i = 0; i < getChildCount(); i++)
{ {
@@ -272,14 +377,14 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); } void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; } virtual bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mElementCount; } U32 getElementCount() const { return mData.size(); }
bool isEmpty() const { return mElementCount == 0; } bool isEmpty() const { return mData.size() == 0; }
//element_list& getData() { return mData; } //element_list& getData() { return mData; }
//const element_list& getData() const { return mData; } //const element_list& getData() const { return mData; }
element_iter getDataBegin() { return mData; } element_iter getDataBegin() { return mData.begin(); }
element_iter getDataEnd() { return mDataEnd; } element_iter getDataEnd() { return mData.end(); }
const_element_iter getDataBegin() const { return mData; } const_element_iter getDataBegin() const { return mData.begin(); }
const_element_iter getDataEnd() const { return mDataEnd; } const_element_iter getDataEnd() const { return mData.end(); }
U32 getChildCount() const { return mChildCount; } U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; } oct_node* getChild(U32 index) { return mChild[index]; }
@@ -359,7 +464,8 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here { //it belongs here
mElementCount++; /*mElementCount++;
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
//avoid unref on uninitialized memory //avoid unref on uninitialized memory
@@ -367,7 +473,14 @@ public:
mData[mElementCount-1] = data; mData[mElementCount-1] = data;
mDataEnd = mData + mElementCount; mDataEnd = mData + mElementCount;
data->setBinIndex(mElementCount-1); data->setBinIndex(mElementCount-1);*/
U32 old_cap = mData.capacity();
data->setBinIndex(mData.size());
mData.push_back(data);
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
BaseType::insert(data); BaseType::insert(data);
return true; return true;
} }
@@ -402,7 +515,8 @@ public:
if( lt == 0x7 ) if( lt == 0x7 )
{ {
mElementCount++; /*mElementCount++;
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
//avoid unref on uninitialized memory //avoid unref on uninitialized memory
@@ -410,7 +524,13 @@ public:
mData[mElementCount-1] = data; mData[mElementCount-1] = data;
mDataEnd = mData + mElementCount; mDataEnd = mData + mElementCount;
data->setBinIndex(mElementCount-1); data->setBinIndex(mElementCount-1);*/
U32 old_cap = mData.capacity();
data->setBinIndex(mData.size());
mData.push_back(data);
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
BaseType::insert(data); BaseType::insert(data);
return true; return true;
} }
@@ -463,10 +583,10 @@ public:
void _remove(T* data, S32 i) void _remove(T* data, S32 i)
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount) { //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
mElementCount--; //mElementCount--;
data->setBinIndex(-1); data->setBinIndex(-1);
if (mElementCount > 0) /* if (mElementCount > 0)
{ {
if (mElementCount != i) if (mElementCount != i)
{ {
@@ -475,15 +595,40 @@ public:
} }
mData[mElementCount] = NULL; //needed for unref mData[mElementCount] = NULL; //needed for unref
OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount);
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount); mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
mDataEnd = mData+mElementCount; mDataEnd = mData+mElementCount;
} }
else else
{ {
mData[0] = NULL; //needed for unref mData[0] = NULL; //needed for unref
OctreeStats::getInstance()->free(1);
free(mData); free(mData);
mData = NULL; mData = NULL;
mDataEnd = NULL; mDataEnd = NULL;
}*/
if(mData.size())
{
if((mData.size()-1)!=i)
{
mData[i] = mData[mData.size()-1];
mData[i]->setBinIndex(i);
}
U32 old_cap = mData.capacity();
mData.pop_back();
if( mData.size() == gOctreeReserveCapacity ||
(mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4))
{
//Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5]
#ifndef LL_DARWIN
mData.shrink_to_fit();
#else
std::vector<LLPointer<T> >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX..
#endif
}
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
} }
this->notifyRemoval(data); this->notifyRemoval(data);
@@ -495,7 +640,8 @@ public:
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
S32 i = data->getBinIndex(); S32 i = data->getBinIndex();
if (i >= 0 && i < (S32)mElementCount) //if (i >= 0 && i < mElementCount)
if (i >= 0 && i < (S32)mData.size())
{ {
if (mData[i] == data) if (mData[i] == data)
{ //found it { //found it
@@ -539,7 +685,8 @@ public:
void removeByAddress(T* data) void removeByAddress(T* data)
{ {
OctreeGuard::checkGuarded(this); OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < mElementCount; ++i) //for (U32 i = 0; i < mElementCount; ++i)
for (U32 i = 0; i < mData.size(); ++i)
{ {
if (mData[i] == data) if (mData[i] == data)
{ //we have data { //we have data
@@ -647,8 +794,6 @@ public:
listener->handleChildRemoval(this, getChild(index)); listener->handleChildRemoval(this, getChild(index));
} }
if (destroy) if (destroy)
{ {
mChild[index]->destroy(); mChild[index]->destroy();
@@ -720,8 +865,8 @@ protected:
U32 mChildCount; U32 mChildCount;
element_list mData; element_list mData;
element_iter mDataEnd; //element_iter mDataEnd;
U32 mElementCount; //U32 mElementCount;
}; };

View File

@@ -83,6 +83,7 @@ U32 LLSpatialGroup::sNodeCount = 0;
std::set<GLuint> LLSpatialGroup::sPendingQueries; std::set<GLuint> LLSpatialGroup::sPendingQueries;
U32 gOctreeMaxCapacity; U32 gOctreeMaxCapacity;
U32 gOctreeReserveCapacity;
BOOL LLSpatialGroup::sNoDelete = FALSE; BOOL LLSpatialGroup::sNoDelete = FALSE;
@@ -4508,251 +4509,27 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
return new LLVertexBuffer(type_mask, usage); return new LLVertexBuffer(type_mask, usage);
} }
LLCullResult::LLCullResult()
{
mVisibleGroupsAllocated = 0;
mAlphaGroupsAllocated = 0;
mOcclusionGroupsAllocated = 0;
mDrawableGroupsAllocated = 0;
mVisibleListAllocated = 0;
mVisibleBridgeAllocated = 0;
mVisibleGroups = NULL;
mVisibleGroupsEnd = NULL;
mAlphaGroups = NULL;
mAlphaGroupsEnd = NULL;
mOcclusionGroups = NULL;
mOcclusionGroupsEnd = NULL;
mDrawableGroups = NULL;
mDrawableGroupsEnd = NULL;
mVisibleList = NULL;
mVisibleListEnd = NULL;
mVisibleBridge = NULL;
mVisibleBridgeEnd = NULL;
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
{
mRenderMap[i] = NULL;
mRenderMapEnd[i] = NULL;
mRenderMapAllocated[i] = 0;
}
clear();
}
void LLCullResult::pushBack(void**& head, U32& count, void* val)
{
count++;
head = (void**) realloc((void*) head, sizeof(void*) * count);
head[count-1] = val;
}
void LLCullResult::clear() void LLCullResult::clear()
{ {
mVisibleGroupsSize = 0; mVisibleGroups.clear();
mVisibleGroupsEnd = mVisibleGroups; mAlphaGroups.clear();
mOcclusionGroups.clear();
mAlphaGroupsSize = 0; mDrawableGroups.clear();
mAlphaGroupsEnd = mAlphaGroups; mVisibleList.clear();
mVisibleBridge.clear();
mOcclusionGroupsSize = 0;
mOcclusionGroupsEnd = mOcclusionGroups;
mDrawableGroupsSize = 0;
mDrawableGroupsEnd = mDrawableGroups;
mVisibleListSize = 0;
mVisibleListEnd = mVisibleList;
mVisibleBridgeSize = 0;
mVisibleBridgeEnd = mVisibleBridge;
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
{ {
for (U32 j = 0; j < mRenderMapSize[i]; j++) mRenderMap[i].clear();
{
mRenderMap[i][j] = 0;
}
mRenderMapSize[i] = 0;
mRenderMapEnd[i] = mRenderMap[i];
} }
} }
LLCullResult::sg_iterator LLCullResult::beginVisibleGroups()
{
return mVisibleGroups;
}
LLCullResult::sg_iterator LLCullResult::endVisibleGroups()
{
return mVisibleGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginAlphaGroups()
{
return mAlphaGroups;
}
LLCullResult::sg_iterator LLCullResult::endAlphaGroups()
{
return mAlphaGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()
{
return mOcclusionGroups;
}
LLCullResult::sg_iterator LLCullResult::endOcclusionGroups()
{
return mOcclusionGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginDrawableGroups()
{
return mDrawableGroups;
}
LLCullResult::sg_iterator LLCullResult::endDrawableGroups()
{
return mDrawableGroupsEnd;
}
LLCullResult::drawable_iterator LLCullResult::beginVisibleList()
{
return mVisibleList;
}
LLCullResult::drawable_iterator LLCullResult::endVisibleList()
{
return mVisibleListEnd;
}
LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge()
{
return mVisibleBridge;
}
LLCullResult::bridge_iterator LLCullResult::endVisibleBridge()
{
return mVisibleBridgeEnd;
}
LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type)
{
return mRenderMap[type];
}
LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type)
{
return mRenderMapEnd[type];
}
void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
{
if (mVisibleGroupsSize < mVisibleGroupsAllocated)
{
mVisibleGroups[mVisibleGroupsSize] = group;
}
else
{
pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group);
}
++mVisibleGroupsSize;
mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize;
}
void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
{
if (mAlphaGroupsSize < mAlphaGroupsAllocated)
{
mAlphaGroups[mAlphaGroupsSize] = group;
}
else
{
pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group);
}
++mAlphaGroupsSize;
mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize;
}
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
{
if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)
{
mOcclusionGroups[mOcclusionGroupsSize] = group;
}
else
{
pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group);
}
++mOcclusionGroupsSize;
mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize;
}
void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
{
if (mDrawableGroupsSize < mDrawableGroupsAllocated)
{
mDrawableGroups[mDrawableGroupsSize] = group;
}
else
{
pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group);
}
++mDrawableGroupsSize;
mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize;
}
void LLCullResult::pushDrawable(LLDrawable* drawable)
{
if (mVisibleListSize < mVisibleListAllocated)
{
mVisibleList[mVisibleListSize] = drawable;
}
else
{
pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable);
}
++mVisibleListSize;
mVisibleListEnd = mVisibleList+mVisibleListSize;
}
void LLCullResult::pushBridge(LLSpatialBridge* bridge)
{
if (mVisibleBridgeSize < mVisibleBridgeAllocated)
{
mVisibleBridge[mVisibleBridgeSize] = bridge;
}
else
{
pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge);
}
++mVisibleBridgeSize;
mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize;
}
void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
{
if (mRenderMapSize[type] < mRenderMapAllocated[type])
{
mRenderMap[type][mRenderMapSize[type]] = draw_info;
}
else
{
pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info);
}
++mRenderMapSize[type];
mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type];
}
void LLCullResult::assertDrawMapsEmpty() void LLCullResult::assertDrawMapsEmpty()
{ {
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
{ {
if (mRenderMapSize[i] != 0) if (hasRenderMap(i))
{ {
llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl;
} }

View File

@@ -546,95 +546,63 @@ public:
class LLCullResult class LLCullResult
{ {
public: public:
LLCullResult(); LLCullResult() {}
typedef LLSpatialGroup** sg_list_t; typedef std::vector<LLSpatialGroup*> sg_list_t;
typedef LLDrawable** drawable_list_t; typedef std::vector<LLDrawable*> drawable_list_t;
typedef LLSpatialBridge** bridge_list_t; typedef std::vector<LLSpatialBridge*> bridge_list_t;
typedef LLDrawInfo** drawinfo_list_t; typedef std::vector<LLDrawInfo*> drawinfo_list_t;
typedef LLSpatialGroup** sg_iterator; typedef sg_list_t::const_iterator sg_iterator;
typedef LLSpatialBridge** bridge_iterator; typedef bridge_list_t::const_iterator bridge_iterator;
typedef LLDrawInfo** drawinfo_iterator; typedef drawinfo_list_t::const_iterator drawinfo_iterator;
typedef LLDrawable** drawable_iterator; typedef drawable_list_t::const_iterator drawable_iterator;
void clear(); void clear();
sg_iterator beginVisibleGroups(); const sg_iterator beginVisibleGroups() const { return mVisibleGroups.begin(); }
sg_iterator endVisibleGroups(); const sg_iterator endVisibleGroups() const { return mVisibleGroups.end(); }
sg_iterator beginAlphaGroups(); const sg_iterator beginAlphaGroups() const { return mAlphaGroups.begin(); }
sg_iterator endAlphaGroups(); const sg_iterator endAlphaGroups() const { return mAlphaGroups.end(); }
const sg_list_t::iterator beginAlphaGroups() { return mAlphaGroups.begin(); }
const sg_list_t::iterator endAlphaGroups() { return mAlphaGroups.end(); }
bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } bool hasOcclusionGroups() const { return !mOcclusionGroups.empty(); }
sg_iterator beginOcclusionGroups(); const sg_iterator beginOcclusionGroups() const { return mOcclusionGroups.begin(); }
sg_iterator endOcclusionGroups(); const sg_iterator endOcclusionGroups() const { return mOcclusionGroups.end(); }
sg_iterator beginDrawableGroups(); const sg_iterator beginDrawableGroups() const { return mDrawableGroups.begin(); }
sg_iterator endDrawableGroups(); const sg_iterator endDrawableGroups() const { return mDrawableGroups.end(); }
drawable_iterator beginVisibleList(); const drawable_iterator beginVisibleList() const { return mVisibleList.begin(); }
drawable_iterator endVisibleList(); const drawable_iterator endVisibleList() const { return mVisibleList.end(); }
bridge_iterator beginVisibleBridge(); const bridge_iterator beginVisibleBridge() const { return mVisibleBridge.begin(); }
bridge_iterator endVisibleBridge(); const bridge_iterator endVisibleBridge() const { return mVisibleBridge.end(); }
drawinfo_iterator beginRenderMap(U32 type); bool hasRenderMap(U32 type) const { return !mRenderMap[type].empty(); }
drawinfo_iterator endRenderMap(U32 type); const drawinfo_iterator beginRenderMap(U32 type)const { return mRenderMap[type].begin(); }
const drawinfo_iterator endRenderMap(U32 type) const { return mRenderMap[type].end(); }
void pushVisibleGroup(LLSpatialGroup* group); void pushVisibleGroup(LLSpatialGroup* group) { mVisibleGroups.push_back(group); }
void pushAlphaGroup(LLSpatialGroup* group); void pushAlphaGroup(LLSpatialGroup* group) { mAlphaGroups.push_back(group); }
void pushOcclusionGroup(LLSpatialGroup* group); void pushOcclusionGroup(LLSpatialGroup* group) { mOcclusionGroups.push_back(group); }
void pushDrawableGroup(LLSpatialGroup* group); void pushDrawableGroup(LLSpatialGroup* group) { mDrawableGroups.push_back(group); }
void pushDrawable(LLDrawable* drawable); void pushDrawable(LLDrawable* drawable) { mVisibleList.push_back(drawable); }
void pushBridge(LLSpatialBridge* bridge); void pushBridge(LLSpatialBridge* bridge) { mVisibleBridge.push_back(bridge); }
void pushDrawInfo(U32 type, LLDrawInfo* draw_info); void pushDrawInfo(U32 type, LLDrawInfo* draw_info) { mRenderMap[type].push_back(draw_info); }
U32 getVisibleGroupsSize() { return mVisibleGroupsSize; }
U32 getAlphaGroupsSize() { return mAlphaGroupsSize; }
U32 getDrawableGroupsSize() { return mDrawableGroupsSize; }
U32 getVisibleListSize() { return mVisibleListSize; }
U32 getVisibleBridgeSize() { return mVisibleBridgeSize; }
U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; }
void assertDrawMapsEmpty(); void assertDrawMapsEmpty();
private: private:
void pushBack(void** &head, U32& count, void* val);
U32 mVisibleGroupsSize;
U32 mAlphaGroupsSize;
U32 mOcclusionGroupsSize;
U32 mDrawableGroupsSize;
U32 mVisibleListSize;
U32 mVisibleBridgeSize;
U32 mVisibleGroupsAllocated;
U32 mAlphaGroupsAllocated;
U32 mOcclusionGroupsAllocated;
U32 mDrawableGroupsAllocated;
U32 mVisibleListAllocated;
U32 mVisibleBridgeAllocated;
U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
sg_list_t mVisibleGroups; sg_list_t mVisibleGroups;
sg_iterator mVisibleGroupsEnd;
sg_list_t mAlphaGroups; sg_list_t mAlphaGroups;
sg_iterator mAlphaGroupsEnd;
sg_list_t mOcclusionGroups; sg_list_t mOcclusionGroups;
sg_iterator mOcclusionGroupsEnd;
sg_list_t mDrawableGroups; sg_list_t mDrawableGroups;
sg_iterator mDrawableGroupsEnd;
drawable_list_t mVisibleList; drawable_list_t mVisibleList;
drawable_iterator mVisibleListEnd;
bridge_list_t mVisibleBridge; bridge_list_t mVisibleBridge;
bridge_iterator mVisibleBridgeEnd;
drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES];
drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
}; };

View File

@@ -434,6 +434,7 @@ static bool handleRepartition(const LLSD&)
if (gPipeline.isInit()) if (gPipeline.isInit())
{ {
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512));
gObjectList.repartitionObjects(); gObjectList.repartitionObjects();
} }
return true; return true;
@@ -634,6 +635,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeReserveNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));

View File

@@ -51,6 +51,7 @@
#include "llhudmanager.h" #include "llhudmanager.h"
#include "llimagebmp.h" #include "llimagebmp.h"
#include "llimagegl.h" #include "llimagegl.h"
#include "lloctree.h"
#include "llselectmgr.h" #include "llselectmgr.h"
#include "llsky.h" #include "llsky.h"
#include "llstartup.h" #include "llstartup.h"
@@ -225,6 +226,7 @@ void display_stats()
F32 fps = gRecentFrameCount / fps_log_freq; F32 fps = gRecentFrameCount / fps_log_freq;
llinfos << llformat("FPS: %.02f", fps) << llendl; llinfos << llformat("FPS: %.02f", fps) << llendl;
llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl; llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl;
OctreStats::getInstance()->dump();
gRecentFrameCount = 0; gRecentFrameCount = 0;
gRecentFPSTime.reset(); gRecentFPSTime.reset();
} }

View File

@@ -401,6 +401,7 @@ void LLPipeline::init()
refreshCachedSettings(); refreshCachedSettings();
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512));
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO");
@@ -9680,25 +9681,25 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
BOOL LLPipeline::hasRenderBatches(const U32 type) const BOOL LLPipeline::hasRenderBatches(const U32 type) const
{ {
return sCull->getRenderMapSize(type) > 0; return sCull->hasRenderMap(type);
} }
LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) const
{ {
return sCull->beginRenderMap(type); return sCull->beginRenderMap(type);
} }
LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) const
{ {
return sCull->endRenderMap(type); return sCull->endRenderMap(type);
} }
LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() const
{ {
return sCull->beginAlphaGroups(); return sCull->beginAlphaGroups();
} }
LLCullResult::sg_iterator LLPipeline::endAlphaGroups() LLCullResult::sg_iterator LLPipeline::endAlphaGroups() const
{ {
return sCull->endAlphaGroups(); return sCull->endAlphaGroups();
} }

View File

@@ -299,10 +299,10 @@ public:
void setLight(LLDrawable *drawablep, BOOL is_light); void setLight(LLDrawable *drawablep, BOOL is_light);
BOOL hasRenderBatches(const U32 type) const; BOOL hasRenderBatches(const U32 type) const;
LLCullResult::drawinfo_iterator beginRenderMap(U32 type); LLCullResult::drawinfo_iterator beginRenderMap(U32 type) const;
LLCullResult::drawinfo_iterator endRenderMap(U32 type); LLCullResult::drawinfo_iterator endRenderMap(U32 type) const;
LLCullResult::sg_iterator beginAlphaGroups(); LLCullResult::sg_iterator beginAlphaGroups() const;
LLCullResult::sg_iterator endAlphaGroups(); LLCullResult::sg_iterator endAlphaGroups() const;
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);