Updates for better DatabasePager peformance w.r.t constant frame rates.
This commit is contained in:
@@ -38,17 +38,17 @@ unsigned int Drawable::s_numberDeletedDrawablesInLastFrame = 0;
|
||||
// static cache of deleted display lists which can only
|
||||
// by completely deleted once the appropriate OpenGL context
|
||||
// is set. Used osg::Drawable::deleteDisplayList(..) and flushDeletedDisplayLists(..) below.
|
||||
typedef std::list<GLuint> DisplayListList;
|
||||
typedef std::map<GLuint,DisplayListList> DeletedDisplayListCache;
|
||||
typedef std::multimap<unsigned int,GLuint> DisplayListMap;
|
||||
typedef std::map<unsigned int,DisplayListMap> DeletedDisplayListCache;
|
||||
|
||||
static OpenThreads::Mutex s_mutex_deletedDisplayListCache;
|
||||
static DeletedDisplayListCache s_deletedDisplayListCache;
|
||||
|
||||
GLuint Drawable::generateDisplayList(unsigned int contextID, unsigned int /*sizeHint*/)
|
||||
GLuint Drawable::generateDisplayList(unsigned int contextID, unsigned int sizeHint)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
|
||||
|
||||
DisplayListList& dll = s_deletedDisplayListCache[contextID];
|
||||
DisplayListMap& dll = s_deletedDisplayListCache[contextID];
|
||||
if (dll.empty())
|
||||
{
|
||||
++s_numberNewDrawablesInLastFrame;
|
||||
@@ -56,11 +56,24 @@ GLuint Drawable::generateDisplayList(unsigned int contextID, unsigned int /*size
|
||||
}
|
||||
else
|
||||
{
|
||||
++s_numberDrawablesReusedLastInLastFrame;
|
||||
// notify(NOTICE)<<"reusing display list "<<std::endl;
|
||||
GLuint globj = dll.back();
|
||||
dll.pop_back();
|
||||
return globj;
|
||||
DisplayListMap::iterator itr = dll.lower_bound(sizeHint);
|
||||
if (itr!=dll.end())
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Reusing a display list of size = "<<itr->first<<" for requested size = "<<sizeHint<<std::endl;
|
||||
|
||||
++s_numberDrawablesReusedLastInLastFrame;
|
||||
|
||||
GLuint globj = itr->second;
|
||||
dll.erase(itr);
|
||||
|
||||
return globj;
|
||||
}
|
||||
else
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Creating a new display list of size = "<<sizeHint<<" although "<<dll.size()<<" are available"<<std::endl;
|
||||
++s_numberNewDrawablesInLastFrame;
|
||||
return glGenLists( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,14 +88,14 @@ unsigned int Drawable::getMinimumNumberOfDisplayListsToRetainInCache()
|
||||
return s_minimumNumberOfDisplayListsToRetainInCache;
|
||||
}
|
||||
|
||||
void Drawable::deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int /*sizeHint*/)
|
||||
void Drawable::deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint)
|
||||
{
|
||||
if (globj!=0)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
|
||||
|
||||
// insert the globj into the cache for the appropriate context.
|
||||
s_deletedDisplayListCache[contextID].push_back(globj);
|
||||
s_deletedDisplayListCache[contextID].insert(DisplayListMap::value_type(sizeHint,globj));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,13 +106,13 @@ void Drawable::flushAllDeletedDisplayLists(unsigned int contextID)
|
||||
DeletedDisplayListCache::iterator citr = s_deletedDisplayListCache.find(contextID);
|
||||
if (citr!=s_deletedDisplayListCache.end())
|
||||
{
|
||||
DisplayListList& dll = citr->second;
|
||||
DisplayListMap& dll = citr->second;
|
||||
|
||||
for(DisplayListList::iterator ditr=dll.begin();
|
||||
for(DisplayListMap::iterator ditr=dll.begin();
|
||||
ditr!=dll.end();
|
||||
++ditr)
|
||||
{
|
||||
glDeleteLists(*ditr,1);
|
||||
glDeleteLists(ditr->second,1);
|
||||
}
|
||||
|
||||
dll.clear();
|
||||
@@ -123,19 +136,60 @@ void Drawable::flushDeletedDisplayLists(unsigned int contextID, double& availabl
|
||||
DeletedDisplayListCache::iterator citr = s_deletedDisplayListCache.find(contextID);
|
||||
if (citr!=s_deletedDisplayListCache.end())
|
||||
{
|
||||
DisplayListList& dll = citr->second;
|
||||
DisplayListMap& dll = citr->second;
|
||||
|
||||
for(DisplayListList::iterator ditr=dll.begin();
|
||||
ditr!=dll.end() && elapsedTime<availableTime && dll.size()>s_minimumNumberOfDisplayListsToRetainInCache;
|
||||
)
|
||||
|
||||
bool trimFromFront = true;
|
||||
if (trimFromFront)
|
||||
{
|
||||
glDeleteLists(*ditr,1);
|
||||
ditr = dll.erase(ditr);
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
++noDeleted;
|
||||
|
||||
++Drawable::s_numberDeletedDrawablesInLastFrame;
|
||||
}
|
||||
unsigned int prev_size = dll.size();
|
||||
|
||||
DisplayListMap::iterator ditr=dll.begin();
|
||||
unsigned int maxNumToDelete = (dll.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? dll.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
|
||||
for(;
|
||||
ditr!=dll.end() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
|
||||
++ditr)
|
||||
{
|
||||
glDeleteLists(ditr->second,1);
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
++noDeleted;
|
||||
|
||||
++Drawable::s_numberDeletedDrawablesInLastFrame;
|
||||
}
|
||||
|
||||
if (ditr!=dll.begin()) dll.erase(dll.begin(),ditr);
|
||||
|
||||
if (noDeleted+dll.size() != prev_size)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Error in delete"<<std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int prev_size = dll.size();
|
||||
|
||||
DisplayListMap::reverse_iterator ditr=dll.rbegin();
|
||||
unsigned int maxNumToDelete = (dll.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? dll.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
|
||||
for(;
|
||||
ditr!=dll.rend() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
|
||||
++ditr)
|
||||
{
|
||||
glDeleteLists(ditr->second,1);
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
++noDeleted;
|
||||
|
||||
++Drawable::s_numberDeletedDrawablesInLastFrame;
|
||||
}
|
||||
|
||||
if (ditr!=dll.rbegin()) dll.erase(ditr.base(),dll.end());
|
||||
|
||||
if (noDeleted+dll.size() != prev_size)
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Error in delete"<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
@@ -156,7 +210,7 @@ void Drawable::deleteVertexBufferObject(unsigned int contextID,GLuint globj)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedVertexBufferObjectCache);
|
||||
|
||||
// insert the globj into the cache for the appropriate context.
|
||||
s_deletedVertexBufferObjectCache[contextID].push_back(globj);
|
||||
s_deletedVertexBufferObjectCache[contextID].insert(DisplayListMap::value_type(0,globj));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,17 +236,18 @@ void Drawable::flushDeletedVertexBufferObjects(unsigned int contextID,double /*c
|
||||
|
||||
unsigned int noDeleted = 0;
|
||||
|
||||
DisplayListList& dll = citr->second;
|
||||
DisplayListMap& dll = citr->second;
|
||||
|
||||
for(DisplayListList::iterator ditr=dll.begin();
|
||||
DisplayListMap::iterator ditr=dll.begin();
|
||||
for(;
|
||||
ditr!=dll.end() && elapsedTime<availableTime;
|
||||
)
|
||||
++ditr)
|
||||
{
|
||||
extensions->glDeleteBuffers(1,&(*ditr));
|
||||
ditr = dll.erase(ditr);
|
||||
extensions->glDeleteBuffers(1,&(ditr->second));
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
++noDeleted;
|
||||
}
|
||||
if (ditr!=dll.begin()) dll.erase(dll.begin(),ditr);
|
||||
|
||||
if (noDeleted!=0) notify(osg::INFO)<<"Number VBOs deleted = "<<noDeleted<<std::endl;
|
||||
}
|
||||
|
||||
@@ -417,6 +417,9 @@ Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop):
|
||||
|
||||
Geometry::~Geometry()
|
||||
{
|
||||
// do dirty here to keep the getGLObjectSizeHint() estimate on the ball
|
||||
dirtyDisplayList();
|
||||
|
||||
// no need to delete, all automatically handled by ref_ptr :-)
|
||||
}
|
||||
|
||||
@@ -745,8 +748,49 @@ bool Geometry::computeFastPathsUsed()
|
||||
|
||||
unsigned int Geometry::getGLObjectSizeHint() const
|
||||
{
|
||||
unsigned int totalSize = 0;
|
||||
if (_vertexData.array.valid()) totalSize += _vertexData.array->getTotalDataSize();
|
||||
|
||||
if (_normalData.array.valid()) totalSize += _normalData.array->getTotalDataSize();
|
||||
|
||||
if (_colorData.array.valid()) totalSize += _colorData.array->getTotalDataSize();
|
||||
|
||||
if (_secondaryColorData.array.valid()) totalSize += _secondaryColorData.array->getTotalDataSize();
|
||||
|
||||
if (_fogCoordData.array.valid()) totalSize += _fogCoordData.array->getTotalDataSize();
|
||||
|
||||
|
||||
unsigned int unit;
|
||||
for(unit=0;unit<_texCoordList.size();++unit)
|
||||
{
|
||||
const Array* array = _texCoordList[unit].array.get();
|
||||
if (array) totalSize += array->getTotalDataSize();
|
||||
|
||||
}
|
||||
|
||||
bool handleVertexAttributes = true;
|
||||
if (handleVertexAttributes)
|
||||
{
|
||||
unsigned int index;
|
||||
for( index = 0; index < _vertexAttribList.size(); ++index )
|
||||
{
|
||||
const Array* array = _vertexAttribList[index].array.get();
|
||||
if (array) totalSize += array->getTotalDataSize();
|
||||
}
|
||||
}
|
||||
|
||||
for(PrimitiveSetList::const_iterator itr=_primitives.begin();
|
||||
itr!=_primitives.end();
|
||||
++itr)
|
||||
{
|
||||
|
||||
totalSize += 4*(*itr)->getNumIndices();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// do a very simply mapping of display list size proportional to vertex datasize.
|
||||
return _vertexData.array.valid() ? _vertexData.array->getNumElements() : 0;
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
void Geometry::drawImplementation(State& state) const
|
||||
@@ -885,7 +929,7 @@ void Geometry::drawImplementation(State& state) const
|
||||
unsigned int index;
|
||||
for( index = 0; index < _vertexAttribList.size(); ++index )
|
||||
{
|
||||
_texCoordList[unit].offset = totalSize;
|
||||
_vertexAttribList[unit].offset = totalSize;
|
||||
const Array* array = _vertexAttribList[index].array.get();
|
||||
const AttributeBinding ab = _vertexAttribList[index].binding;
|
||||
if( ab == BIND_PER_VERTEX && array )
|
||||
|
||||
@@ -226,14 +226,72 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
|
||||
}
|
||||
}
|
||||
|
||||
static double s_start_frame = 0;
|
||||
static double s_before_compile = 0;
|
||||
static double s_after_compile = 0;
|
||||
static osg::Timer_t startTick = 0;
|
||||
|
||||
void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
|
||||
{
|
||||
|
||||
if (framestamp)
|
||||
{
|
||||
//osg::notify(osg::INFO) << "signalBeginFrame "<<framestamp->getFrameNumber()<<">>>>>>>>>>>>>>>>"<<std::endl;
|
||||
_frameNumber = framestamp->getFrameNumber();
|
||||
|
||||
|
||||
} //else osg::notify(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<<std::endl;
|
||||
|
||||
if (startTick==0) startTick = osg::Timer::instance()->tick();
|
||||
|
||||
double timeStamp = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
double drawTime = s_before_compile-s_start_frame;
|
||||
double compileTime = s_after_compile-s_before_compile;
|
||||
double timeDelta = timeStamp-s_start_frame;
|
||||
|
||||
unsigned int numFrames = (timeDelta*60.0074);
|
||||
/*
|
||||
if (timeDelta>0.02)
|
||||
{
|
||||
std::string str;
|
||||
if (osg::Texture::s_numberTextureReusedLastInLastFrame > 0) str += " RT ";
|
||||
if (osg::Texture::s_numberNewTextureInLastFrame > 0) str += " NT ";
|
||||
if (osg::Texture::s_numberDeletedTextureInLastFrame > 0) str += " DT ";
|
||||
if (osg::Drawable::s_numberDrawablesReusedLastInLastFrame > 0) str += " RD ";
|
||||
if (osg::Drawable::s_numberNewDrawablesInLastFrame > 0) str += " ND ";
|
||||
if (osg::Drawable::s_numberDeletedDrawablesInLastFrame > 0) str += " DD ";
|
||||
|
||||
if (str.empty()) str += " ?? ";
|
||||
|
||||
osg::notify(osg::NOTICE)<<" ************* frame="<<timeDelta<<"\tdraw="<<drawTime<<"\tcompile="<<compileTime<<" ***** FRAMES DROPPED ********** "<<str<<std::dec<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberTextureReusedLastInLastFrame = "<<osg::Texture::s_numberTextureReusedLastInLastFrame<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberNewTextureInLastFrame = "<<osg::Texture::s_numberNewTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberDeletedTextureInLastFrame = "<<osg::Texture::s_numberDeletedTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDrawablesReusedLastInLastFrame = "<<osg::Drawable::s_numberDrawablesReusedLastInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberNewDrawablesInLastFrame = "<<osg::Drawable::s_numberNewDrawablesInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDeletedDrawablesInLastFrame = "<<osg::Drawable::s_numberDeletedDrawablesInLastFrame <<std::endl;
|
||||
|
||||
}
|
||||
*/
|
||||
s_start_frame = timeStamp;
|
||||
|
||||
osg::Texture::s_numberTextureReusedLastInLastFrame = 0;
|
||||
osg::Texture::s_numberNewTextureInLastFrame = 0;
|
||||
osg::Texture::s_numberDeletedTextureInLastFrame = 0;
|
||||
osg::Drawable::s_numberDrawablesReusedLastInLastFrame = 0;
|
||||
osg::Drawable::s_numberNewDrawablesInLastFrame = 0;
|
||||
osg::Drawable::s_numberDeletedDrawablesInLastFrame = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_frameBlock->reset();
|
||||
|
||||
if (_threadPriorityDuringFrame!=getSchedulePriority())
|
||||
@@ -353,12 +411,10 @@ void DatabasePager::run()
|
||||
osg::notify(osg::INFO)<<"DatabasePager::run()"<<std::endl;
|
||||
|
||||
// need to set the texture object manager to be able to reuse textures
|
||||
// by keeping deleted texture objects around for 10 seconds after being deleted.
|
||||
osg::Texture::setMinimumNumberOfTextureObjectsToRetainInCache(100);
|
||||
|
||||
// need to set the texture object manager to be able to reuse textures
|
||||
// by keeping deleted texture objects around for 10 seconds after being deleted.
|
||||
osg::Drawable::setMinimumNumberOfDisplayListsToRetainInCache(2000);
|
||||
osg::Drawable::setMinimumNumberOfDisplayListsToRetainInCache(500);
|
||||
|
||||
bool firstTime = true;
|
||||
|
||||
@@ -526,34 +582,7 @@ void DatabasePager::run()
|
||||
|
||||
void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
|
||||
{
|
||||
/*
|
||||
static double s_previous = timeStamp;
|
||||
double timeDelta = timeStamp-s_previous;
|
||||
if (timeDelta>0.02)
|
||||
{
|
||||
std::string str;
|
||||
if (osg::Texture::s_numberTextureReusedLastInLastFrame > 0) str += " RT ";
|
||||
if (osg::Texture::s_numberNewTextureInLastFrame > 0) str += " NT ";
|
||||
if (osg::Texture::s_numberDeletedTextureInLastFrame > 0) str += " DT ";
|
||||
if (osg::Drawable::s_numberDrawablesReusedLastInLastFrame > 0) str += " RD ";
|
||||
if (osg::Drawable::s_numberNewDrawablesInLastFrame > 0) str += " ND ";
|
||||
if (osg::Drawable::s_numberDeletedDrawablesInLastFrame > 0) str += " DD ";
|
||||
|
||||
if (str.empty()) str += " ?? ";
|
||||
|
||||
osg::notify(osg::NOTICE)<<"addLoadedDataToSceneGraph "<<timeDelta;
|
||||
osg::notify(osg::NOTICE)<<" ************* FRAME DROP ********** "<<str<<std::dec<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberTextureReusedLastInLastFrame = "<<osg::Texture::s_numberTextureReusedLastInLastFrame<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberNewTextureInLastFrame = "<<osg::Texture::s_numberNewTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberDeletedTextureInLastFrame = "<<osg::Texture::s_numberDeletedTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDrawablesReusedLastInLastFrame = "<<osg::Drawable::s_numberDrawablesReusedLastInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberNewDrawablesInLastFrame = "<<osg::Drawable::s_numberNewDrawablesInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDeletedDrawablesInLastFrame = "<<osg::Drawable::s_numberDeletedDrawablesInLastFrame <<std::endl;
|
||||
|
||||
}
|
||||
|
||||
s_previous = timeStamp;
|
||||
*/
|
||||
// osg::Timer_t before = osg::Timer::instance()->tick();
|
||||
|
||||
DatabaseRequestList localFileLoadedList;
|
||||
@@ -592,12 +621,6 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Done DatabasePager::addLoadedDataToSceneGraph"<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms objects"<<localFileLoadedList.size()<<std::endl;
|
||||
|
||||
osg::Texture::s_numberTextureReusedLastInLastFrame = 0;
|
||||
osg::Texture::s_numberNewTextureInLastFrame = 0;
|
||||
osg::Texture::s_numberDeletedTextureInLastFrame = 0;
|
||||
osg::Drawable::s_numberDrawablesReusedLastInLastFrame = 0;
|
||||
osg::Drawable::s_numberNewDrawablesInLastFrame = 0;
|
||||
osg::Drawable::s_numberDeletedDrawablesInLastFrame = 0;
|
||||
}
|
||||
|
||||
void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
|
||||
@@ -646,7 +669,7 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
|
||||
|
||||
unsigned int i = 0;
|
||||
// unsigned int numberOfPagedLODToTest = _inactivePagedLODList.size();
|
||||
unsigned int targetNumOfInActivePagedLODs = 1000;
|
||||
unsigned int targetNumOfInActivePagedLODs = 100;
|
||||
unsigned int targetNumOfRemovedChildPagedLODs = 0;
|
||||
if (_inactivePagedLODList.size()>targetNumOfInActivePagedLODs) targetNumOfRemovedChildPagedLODs = _inactivePagedLODList.size()-targetNumOfInActivePagedLODs;
|
||||
|
||||
@@ -793,169 +816,187 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<<std::endl;
|
||||
|
||||
const osg::Timer& timer = *osg::Timer::instance();
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
double elapsedTime = 0.0;
|
||||
double estimatedTextureDuration = 0.0;
|
||||
double estimatedDrawableDuration = 0.0;
|
||||
|
||||
osg::ref_ptr<DatabaseRequest> databaseRequest;
|
||||
|
||||
// get the first compileable entry.
|
||||
s_before_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
|
||||
double drawTime = s_before_compile-s_start_frame;
|
||||
if (drawTime<0.01)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
if (!_dataToCompileList.empty())
|
||||
|
||||
const osg::Timer& timer = *osg::Timer::instance();
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
double elapsedTime = 0.0;
|
||||
double estimatedTextureDuration = 0.0;
|
||||
double estimatedDrawableDuration = 0.0;
|
||||
|
||||
osg::ref_ptr<DatabaseRequest> databaseRequest;
|
||||
|
||||
// get the first compileable entry.
|
||||
{
|
||||
std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor());
|
||||
|
||||
DatabaseRequestList::iterator litr;
|
||||
int i=0;
|
||||
for(litr = _dataToCompileList.begin();
|
||||
(litr != _dataToCompileList.end()) && (_frameNumber == (*litr)->_frameNumberLastRequest);
|
||||
++litr,i++)
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"Compile "<<_frameNumber-(*litr)->_frameNumberLastRequest<<std::endl;
|
||||
}
|
||||
if (litr != _dataToCompileList.end())
|
||||
{
|
||||
if (_deleteRemovedSubgraphsInDatabaseThread)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_childrenToDeleteListMutex);
|
||||
|
||||
for(DatabaseRequestList::iterator ditr=litr;
|
||||
ditr!=_dataToCompileList.end();
|
||||
++ditr)
|
||||
{
|
||||
_childrenToDeleteList.push_back((*ditr)->_loadedModel.get());
|
||||
}
|
||||
}
|
||||
//osg::notify(osg::NOTICE)<<"Pruning "<<_dataToCompileList.size()-i<<std::endl;
|
||||
_dataToCompileList.erase(litr,_dataToCompileList.end());
|
||||
}
|
||||
|
||||
|
||||
databaseRequest = _dataToCompileList.front();
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int numObjectsCompiled = 0;
|
||||
unsigned int maxNumObjectsToCompile = 4;
|
||||
|
||||
// while there are valid databaseRequest's in the to compile list and there is
|
||||
// sufficient time left compile each databaseRequest's stateset and drawables.
|
||||
while (databaseRequest.valid() && elapsedTime<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
|
||||
DataToCompile& dtc = dcm[state.getContextID()];
|
||||
if (!dtc.first.empty() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
|
||||
|
||||
// we have StateSet's to compile
|
||||
StateSetList& sslist = dtc.first;
|
||||
//osg::notify(osg::INFO)<<"Compiling statesets"<<std::endl;
|
||||
StateSetList::iterator itr=sslist.begin();
|
||||
for(;
|
||||
itr!=sslist.end() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile;
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling stateset "<<(*itr).get()<<std::endl;
|
||||
|
||||
double startCompileTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
(*itr)->compileGLObjects(state);
|
||||
|
||||
GLint p;
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_RESIDENT, &p);
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
|
||||
// estimate the duration of the compile based on current compile duration.
|
||||
estimatedTextureDuration = (elapsedTime-startCompileTime);
|
||||
|
||||
++numObjectsCompiled;
|
||||
}
|
||||
// remove the compiled stateset from the list.
|
||||
sslist.erase(sslist.begin(),itr);
|
||||
}
|
||||
|
||||
if (!dtc.second.empty() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
// we have Drawable's to compile
|
||||
//osg::notify(osg::INFO)<<"Compiling drawables"<<std::endl;
|
||||
DrawableList& dwlist = dtc.second;
|
||||
DrawableList::iterator itr=dwlist.begin();
|
||||
for(;
|
||||
itr!=dwlist.end() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile;
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
|
||||
double startCompileTime = timer.delta_s(start_tick,timer.tick());
|
||||
(*itr)->compileGLObjects(state);
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
// estimate the duration of the compile based on current compile duration.
|
||||
estimatedDrawableDuration = (elapsedTime-startCompileTime);
|
||||
|
||||
++numObjectsCompiled;
|
||||
|
||||
}
|
||||
// remove the compiled drawables from the list.
|
||||
dwlist.erase(dwlist.begin(),itr);
|
||||
}
|
||||
|
||||
//osg::notify(osg::INFO)<<"Checking if compiled"<<std::endl;
|
||||
|
||||
// now check the to compile entries for all active graphics contexts
|
||||
// to make sure that all have been compiled.
|
||||
bool allCompiled = true;
|
||||
for(DataToCompileMap::iterator itr=dcm.begin();
|
||||
itr!=dcm.end() && allCompiled;
|
||||
++itr)
|
||||
{
|
||||
if (!(itr->second.first.empty())) allCompiled=false;
|
||||
if (!(itr->second.second.empty())) allCompiled=false;
|
||||
}
|
||||
|
||||
|
||||
if (allCompiled)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"All compiled"<<std::endl;
|
||||
|
||||
// we've compile all of the current databaseRequest so we can now pop it off the
|
||||
// to compile list and place it on the merge list.
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
|
||||
_dataToMergeList.push_back(databaseRequest);
|
||||
}
|
||||
|
||||
if (!_dataToCompileList.empty()) _dataToCompileList.erase(_dataToCompileList.begin());
|
||||
|
||||
if (!_dataToCompileList.empty())
|
||||
{
|
||||
std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor());
|
||||
|
||||
DatabaseRequestList::iterator litr;
|
||||
int i=0;
|
||||
for(litr = _dataToCompileList.begin();
|
||||
(litr != _dataToCompileList.end()) && (_frameNumber == (*litr)->_frameNumberLastRequest);
|
||||
++litr,i++)
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"Compile "<<_frameNumber-(*litr)->_frameNumberLastRequest<<std::endl;
|
||||
}
|
||||
if (litr != _dataToCompileList.end())
|
||||
{
|
||||
if (_deleteRemovedSubgraphsInDatabaseThread)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_childrenToDeleteListMutex);
|
||||
|
||||
for(DatabaseRequestList::iterator ditr=litr;
|
||||
ditr!=_dataToCompileList.end();
|
||||
++ditr)
|
||||
{
|
||||
_childrenToDeleteList.push_back((*ditr)->_loadedModel.get());
|
||||
}
|
||||
}
|
||||
//osg::notify(osg::NOTICE)<<"Pruning "<<_dataToCompileList.size()-i<<std::endl;
|
||||
_dataToCompileList.erase(litr,_dataToCompileList.end());
|
||||
}
|
||||
|
||||
|
||||
databaseRequest = _dataToCompileList.front();
|
||||
}
|
||||
else databaseRequest = 0;
|
||||
};
|
||||
|
||||
}
|
||||
else
|
||||
unsigned int numObjectsCompiled = 0;
|
||||
unsigned int maxNumObjectsToCompile = 4;
|
||||
|
||||
// while there are valid databaseRequest's in the to compile list and there is
|
||||
// sufficient time left compile each databaseRequest's stateset and drawables.
|
||||
while (databaseRequest.valid() && elapsedTime<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<"Not all compiled"<<std::endl;
|
||||
databaseRequest = 0;
|
||||
DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
|
||||
DataToCompile& dtc = dcm[state.getContextID()];
|
||||
if (!dtc.first.empty() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
|
||||
|
||||
// we have StateSet's to compile
|
||||
StateSetList& sslist = dtc.first;
|
||||
//osg::notify(osg::INFO)<<"Compiling statesets"<<std::endl;
|
||||
StateSetList::iterator itr=sslist.begin();
|
||||
for(;
|
||||
itr!=sslist.end() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile;
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling stateset "<<(*itr).get()<<std::endl;
|
||||
|
||||
double startCompileTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
(*itr)->compileGLObjects(state);
|
||||
|
||||
GLint p;
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_RESIDENT, &p);
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
|
||||
// estimate the duration of the compile based on current compile duration.
|
||||
estimatedTextureDuration = (elapsedTime-startCompileTime);
|
||||
|
||||
++numObjectsCompiled;
|
||||
}
|
||||
// remove the compiled stateset from the list.
|
||||
sslist.erase(sslist.begin(),itr);
|
||||
}
|
||||
|
||||
if (!dtc.second.empty() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
{
|
||||
// we have Drawable's to compile
|
||||
//osg::notify(osg::INFO)<<"Compiling drawables"<<std::endl;
|
||||
DrawableList& dwlist = dtc.second;
|
||||
DrawableList::iterator itr=dwlist.begin();
|
||||
for(;
|
||||
itr!=dwlist.end() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<maxNumObjectsToCompile;
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
|
||||
double startCompileTime = timer.delta_s(start_tick,timer.tick());
|
||||
(*itr)->compileGLObjects(state);
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
// estimate the duration of the compile based on current compile duration.
|
||||
estimatedDrawableDuration = (elapsedTime-startCompileTime);
|
||||
|
||||
// osg::notify(osg::NOTICE)<<" Compiling drawable "<<estimatedDrawableDuration<<std::endl;
|
||||
|
||||
++numObjectsCompiled;
|
||||
|
||||
}
|
||||
// remove the compiled drawables from the list.
|
||||
dwlist.erase(dwlist.begin(),itr);
|
||||
}
|
||||
|
||||
//osg::notify(osg::INFO)<<"Checking if compiled"<<std::endl;
|
||||
|
||||
// now check the to compile entries for all active graphics contexts
|
||||
// to make sure that all have been compiled.
|
||||
bool allCompiled = true;
|
||||
for(DataToCompileMap::iterator itr=dcm.begin();
|
||||
itr!=dcm.end() && allCompiled;
|
||||
++itr)
|
||||
{
|
||||
if (!(itr->second.first.empty())) allCompiled=false;
|
||||
if (!(itr->second.second.empty())) allCompiled=false;
|
||||
}
|
||||
|
||||
|
||||
if (allCompiled)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"All compiled"<<std::endl;
|
||||
|
||||
// we've compile all of the current databaseRequest so we can now pop it off the
|
||||
// to compile list and place it on the merge list.
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
|
||||
_dataToMergeList.push_back(databaseRequest);
|
||||
}
|
||||
|
||||
if (!_dataToCompileList.empty()) _dataToCompileList.erase(_dataToCompileList.begin());
|
||||
|
||||
if (!_dataToCompileList.empty())
|
||||
{
|
||||
std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor());
|
||||
databaseRequest = _dataToCompileList.front();
|
||||
}
|
||||
else databaseRequest = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//osg::notify(osg::INFO)<<"Not all compiled"<<std::endl;
|
||||
databaseRequest = 0;
|
||||
}
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
}
|
||||
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
// availableTime -= elapsedTime;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<" time remaining ="<<availableTime<<std::endl;
|
||||
//osg::notify(osg::NOTICE)<<"estimatedTextureDuration="<<estimatedTextureDuration;
|
||||
//osg::notify(osg::NOTICE)<<"\testimatedDrawableDuration="<<estimatedDrawableDuration<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
availableTime = 0.0f;
|
||||
}
|
||||
|
||||
availableTime -= elapsedTime;
|
||||
s_after_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<" time remaining ="<<availableTime<<std::endl;
|
||||
//osg::notify(osg::NOTICE)<<"estimatedTextureDuration="<<estimatedTextureDuration;
|
||||
//osg::notify(osg::NOTICE)<<"\testimatedDrawableDuration="<<estimatedDrawableDuration<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -509,14 +509,15 @@ public:
|
||||
#if 1
|
||||
double availableTime = 0.0025; // 2.5 ms
|
||||
|
||||
// flush deleted GL objects.
|
||||
sh.getSceneView()->flushDeletedGLObjects(availableTime);
|
||||
|
||||
// compile any GL objects that are required.
|
||||
if (dp) dp->compileGLObjects(*(sh.getSceneView()->getState()),availableTime);
|
||||
|
||||
// flush deleted GL objects.
|
||||
sh.getSceneView()->flushDeletedGLObjects(availableTime);
|
||||
#endif
|
||||
|
||||
if (dp) dp->signalEndFrame();
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
@@ -542,6 +543,9 @@ public:
|
||||
// compile any GL objects that are required.
|
||||
if (dp) dp->compileGLObjects(*(_sceneView->getState()),availableTime);
|
||||
#endif
|
||||
|
||||
// glFinish();
|
||||
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgUtil::SceneView> _sceneView;
|
||||
|
||||
Reference in New Issue
Block a user