Added the ability to release OpenGL objects in PagedLOD subgrphs that are no longer being rendered.

This commit is contained in:
Robert Osfield
2008-10-07 11:35:41 +00:00
parent 6ec4c64914
commit 8c98220878
6 changed files with 142 additions and 3 deletions

View File

@@ -23,7 +23,8 @@ PagedLOD::PerRangeData::PerRangeData():
_priorityOffset(0.0f),
_priorityScale(1.0f),
_timeStamp(0.0f),
_frameNumber(0) {}
_frameNumber(0),
_frameNumberOfLastReleaseGLObjects(0) {}
PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd):
_filename(prd._filename),
@@ -31,6 +32,7 @@ PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd):
_priorityScale(prd._priorityScale),
_timeStamp(prd._timeStamp),
_frameNumber(prd._frameNumber),
_frameNumberOfLastReleaseGLObjects(prd._frameNumberOfLastReleaseGLObjects),
_databaseRequest(prd._databaseRequest) {}
PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd)
@@ -41,6 +43,7 @@ PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData&
_priorityScale = prd._priorityScale;
_timeStamp = prd._timeStamp;
_frameNumber = prd._frameNumber;
_frameNumberOfLastReleaseGLObjects = prd._frameNumberOfLastReleaseGLObjects;
_databaseRequest = prd._databaseRequest;
return *this;
}
@@ -288,3 +291,23 @@ bool PagedLOD::removeExpiredChildren(double expiryTime, int expiryFrame, NodeLis
}
return false;
}
bool PagedLOD::releaseGLObjectsOnExpiredChildren(double releaseTime, int releaseFrame)
{
unsigned int numChildrenReleased = 0;
unsigned int numChildren = osg::minimum(_perRangeDataList.size(), _children.size());
for(unsigned int i=_numChildrenThatCannotBeExpired; i<numChildren; ++i)
{
if (_perRangeDataList[i]._frameNumberOfLastReleaseGLObjects != _perRangeDataList[i]._frameNumber &&
_perRangeDataList[i]._timeStamp<releaseTime &&
_perRangeDataList[i]._frameNumber<releaseFrame)
{
_perRangeDataList[i]._frameNumberOfLastReleaseGLObjects = _perRangeDataList[i]._frameNumber;
_children[i]->releaseGLObjects();
++numChildrenReleased;
}
}
return numChildrenReleased>0;
}

View File

@@ -46,6 +46,8 @@ static osg::ApplicationUsageProxy DatabasePager_e3(osg::ApplicationUsage::ENVIRO
static osg::ApplicationUsageProxy DatabasePager_e4(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DATABASE_PAGER_PRIORITY <mode>", "Set the thread priority to DEFAULT, MIN, LOW, NOMINAL, HIGH or MAX.");
static osg::ApplicationUsageProxy DatabasePager_e7(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EXPIRY_DELAY <float> ","Set the length of time a PagedLOD child is kept in memory, without being used, before its tagged as expired, and ear marked to deletion.");
static osg::ApplicationUsageProxy DatabasePager_e8(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EXPIRY_FRAMES <int> ","Set number of frames a PagedLOD child is kept in memory, without being used, before its tagged as expired, and ear marked to deletion.");
static osg::ApplicationUsageProxy DatabasePager_e9(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RELEASE_DELAY <float> ","Set the length of time a PagedLOD child's OpenGL objects are kept in memory, without being used, before be released (setting to OFF disables this feature.)");
static osg::ApplicationUsageProxy DatabasePager_e10(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RELEASE_FRAMES <int> ","Set number of frames a PagedLOD child's OpenGL objects are kept in memory, without being used, before be released.");
// Convert function objects that take pointer args into functions that a
// reference to an osg::ref_ptr. This is quite useful for doing STL
// operations on lists of ref_ptr. This code assumes that a function
@@ -880,8 +882,6 @@ DatabasePager::DatabasePager()
}
}
_changeAutoUnRef = true;
_valueAutoUnRef = true;
_changeAnisotropy = false;
_valueAnisotropy = 1.0f;
@@ -911,6 +911,31 @@ DatabasePager::DatabasePager()
osg::notify(osg::NOTICE)<<"Expiry frames = "<<_expiryFrames<<std::endl;
}
if( (ptr = getenv("OSG_RELEASE_DELAY")) != 0)
{
if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"Off")==0 || strcmp(ptr,"off")==0)
{
setReleaseDelay(DBL_MAX);
}
else
{
setReleaseDelay(atof(ptr));
}
osg::notify(osg::NOTICE)<<"Release delay = "<<_releaseDelay<<std::endl;
}
else
{
setReleaseDelay(DBL_MAX);
}
_releaseFrames = 1; // Last frame will not be release
if( (ptr = getenv("OSG_RELEASE_FRAMES")) != 0)
{
_releaseFrames = atoi(ptr);
osg::notify(osg::NOTICE)<<"Release frames = "<<_releaseFrames<<std::endl;
}
_doPreCompile = true;
if( (ptr = getenv("OSG_DO_PRE_COMPILE")) != 0)
{
@@ -988,6 +1013,10 @@ DatabasePager::DatabasePager(const DatabasePager& rhs)
_expiryDelay = rhs._expiryDelay;
_expiryFrames = rhs._expiryFrames;
_releaseDelay = rhs._releaseDelay;
_releaseFrames = rhs._releaseFrames;
_doPreCompile = rhs._doPreCompile;
_targetFrameRate = rhs._targetFrameRate;
_minimumTimeAvailableForGLCompileAndDeletePerFrame = rhs._minimumTimeAvailableForGLCompileAndDeletePerFrame;
@@ -1029,6 +1058,23 @@ DatabasePager* DatabasePager::create()
new DatabasePager;
}
void DatabasePager::setReleaseDelay(double releaseDelay)
{
_releaseDelay = releaseDelay;
if (_releaseDelay==DBL_MAX)
{
_changeAutoUnRef = true;
_valueAutoUnRef = true;
}
else
{
// when GLObject release is used make sure Images aren't unref'd as they may be needed later.
_changeAutoUnRef = true;
_valueAutoUnRef = false;
}
}
int DatabasePager::setSchedulePriority(OpenThreads::Thread::ThreadPriority priority)
{
int result = 0;
@@ -1393,9 +1439,14 @@ void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp &frameStamp)
{
// osg::notify(osg::NOTICE)<<"DatabasePager::new_removeExpiredSubgraphs()"<<std::endl;
double expiryTime = frameStamp.getReferenceTime() - _expiryDelay;
int expiryFrame = frameStamp.getFrameNumber() - _expiryFrames;
double releaseTime = frameStamp.getReferenceTime() - _releaseDelay;
int releaseFrame = frameStamp.getFrameNumber() - _releaseFrames;
osg::NodeList childrenRemoved;
for(PagedLODList::iterator itr = _pagedLODList.begin();
@@ -1403,6 +1454,13 @@ void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp &frameStamp)
++itr)
{
osg::PagedLOD* plod = itr->get();
if (_releaseDelay!=DBL_MAX && plod->releaseGLObjectsOnExpiredChildren(releaseTime, releaseFrame))
{
osg::notify(osg::INFO)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<<std::endl;
}
plod->removeExpiredChildren(expiryTime, expiryFrame, childrenRemoved);
}

View File

@@ -213,6 +213,11 @@ BEGIN_OBJECT_REFLECTOR(osg::PagedLOD)
__bool__removeExpiredChildren__double__int__NodeList_R1,
"Remove the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
"The removed children are added to the removeChildren list passed into the method, this allows the children to be deleted later at the caller's discretion. Return true if children are removed, false otherwise. ");
I_Method2(bool, releaseGLObjectsOnExpiredChildren, IN, double, releaseTime, IN, int, releaseFrame,
Properties::VIRTUAL,
__bool__releaseGLObjectsOnExpiredChildren__double__int,
"Release the GL Objects of the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. ",
"Return true if any children have release called upon them, false otherwise. ");
I_ProtectedMethod1(void, expandPerRangeDataTo, IN, unsigned int, pos,
Properties::NON_VIRTUAL,
Properties::NON_CONST,
@@ -280,6 +285,7 @@ BEGIN_VALUE_REFLECTOR(osg::PagedLOD::PerRangeData)
I_PublicMemberProperty(float, _priorityScale);
I_PublicMemberProperty(double, _timeStamp);
I_PublicMemberProperty(int, _frameNumber);
I_PublicMemberProperty(int, _frameNumberOfLastReleaseGLObjects);
I_PublicMemberProperty(osg::ref_ptr< osg::Referenced >, _databaseRequest);
END_REFLECTOR

View File

@@ -214,6 +214,26 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
__int__getExpiryFrames,
"Get the number of frames that a subgraph will be kept without being visited in the cull traversal before being removed. ",
"");
I_Method1(void, setReleaseDelay, IN, double, releaseDelay,
Properties::NON_VIRTUAL,
__void__setReleaseDelay__double,
"Set the amount of time that a subgraph's OpenGL objects will be kept without being visited in the cull traversal before being released. ",
"");
I_Method0(double, getReleaseDelay,
Properties::NON_VIRTUAL,
__double__getReleaseDelay,
"Get the amount of time that a subgraph's OpenGL objects will be kept without being visited in the cull traversal before being released. ",
"");
I_Method1(void, setReleaseFrames, IN, int, releaseFrames,
Properties::NON_VIRTUAL,
__void__setReleaseFrames__int,
"Set the number of frames that a subgraph's OpenGL objects will be kept without being visited in the cull traversal before being released. ",
"");
I_Method0(int, getReleaseFrames,
Properties::NON_VIRTUAL,
__int__getReleaseFrames,
"Get the number of frames that a subgraph's OpenGL objects will be kept without being visited in the cull traversal before being released. ",
"");
I_Method1(void, setDeleteRemovedSubgraphsInDatabaseThread, IN, bool, flag,
Properties::NON_VIRTUAL,
__void__setDeleteRemovedSubgraphsInDatabaseThread__bool,
@@ -415,6 +435,12 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
I_SimpleProperty(double, MinimumTimeToMergeTile,
__double__getMinimumTimeToMergeTile,
0);
I_SimpleProperty(double, ReleaseDelay,
__double__getReleaseDelay,
__void__setReleaseDelay__double);
I_SimpleProperty(int, ReleaseFrames,
__int__getReleaseFrames,
__void__setReleaseFrames__int);
I_SimpleProperty(OpenThreads::Thread::ThreadPriority, SchedulePriority,
0,
__int__setSchedulePriority__OpenThreads_Thread_ThreadPriority);