Added the ability to release OpenGL objects in PagedLOD subgrphs that are no longer being rendered.
This commit is contained in:
parent
6ec4c64914
commit
8c98220878
@ -63,6 +63,7 @@ class OSG_EXPORT PagedLOD : public LOD
|
||||
float _priorityScale;
|
||||
double _timeStamp;
|
||||
int _frameNumber;
|
||||
int _frameNumberOfLastReleaseGLObjects;
|
||||
osg::ref_ptr<osg::Referenced> _databaseRequest;
|
||||
};
|
||||
|
||||
@ -122,6 +123,10 @@ class OSG_EXPORT PagedLOD : public LOD
|
||||
* Return true if children are removed, false otherwise. */
|
||||
virtual bool removeExpiredChildren(double expiryTime, int expiryFrame, NodeList& removedChildren);
|
||||
|
||||
/** 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. */
|
||||
virtual bool releaseGLObjectsOnExpiredChildren(double releaseTime, int releaseFrame);
|
||||
|
||||
protected :
|
||||
|
||||
virtual ~PagedLOD();
|
||||
|
@ -216,6 +216,24 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
* before being removed.*/
|
||||
int getExpiryFrames() const { return _expiryFrames; }
|
||||
|
||||
|
||||
/** Set the amount of time that a subgraph's OpenGL objects will be kept without being visited in the cull traversal
|
||||
* before being released.*/
|
||||
void setReleaseDelay(double releaseDelay);
|
||||
|
||||
/** Get the amount of time that a subgraph's OpenGL objects will be kept without being visited in the cull traversal
|
||||
* before being released.*/
|
||||
double getReleaseDelay() const { return _releaseDelay; }
|
||||
|
||||
/** Set the number of frames that a subgraph's OpenGL objects will be kept without being visited in the cull traversal
|
||||
* before being released.*/
|
||||
void setReleaseFrames(int releaseFrames) { _releaseFrames = releaseFrames; }
|
||||
|
||||
/** Get the number of frames that a subgraph's OpenGL objects will be kept without being visited in the cull traversal
|
||||
* before being released.*/
|
||||
int getReleaseFrames() const { return _releaseFrames; }
|
||||
|
||||
|
||||
/** Set whether the removed subgraphs should be deleted in the database thread or not.*/
|
||||
void setDeleteRemovedSubgraphsInDatabaseThread(bool flag) { _deleteRemovedSubgraphsInDatabaseThread = flag; }
|
||||
|
||||
@ -534,6 +552,9 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
double _expiryDelay;
|
||||
int _expiryFrames;
|
||||
|
||||
double _releaseDelay;
|
||||
int _releaseFrames;
|
||||
|
||||
ActiveGraphicsContexts _activeGraphicsContexts;
|
||||
// CompileGraphicsContexts _compileGraphicsContexts;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user