Introduced memory pool size management

This commit is contained in:
Robert Osfield
2009-09-23 13:51:20 +00:00
parent 3d75054e2c
commit d56499025b
4 changed files with 146 additions and 45 deletions

View File

@@ -812,7 +812,8 @@ class OSG_EXPORT Texture : public osg::StateAttribute
_width(0),
_height(0),
_depth(0),
_border(0) {}
_border(0),
_size(0) {}
inline TextureProfile(GLenum target,
GLint numMipmapLevels,
@@ -827,7 +828,8 @@ class OSG_EXPORT Texture : public osg::StateAttribute
_width(width),
_height(height),
_depth(depth),
_border(border) {}
_border(border),
_size(0) { computeSize(); }
#define LESSTHAN(A,B) if (A<B) return true; if (B<A) return false;
@@ -835,6 +837,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute
bool operator < (const TextureProfile& rhs) const
{
LESSTHAN(_size,rhs._size);
LESSTHAN(_target,rhs._target);
LESSTHAN(_numMipmapLevels,rhs._numMipmapLevels);
LESSTHAN(_internalFormat,rhs._internalFormat);
@@ -887,13 +890,16 @@ class OSG_EXPORT Texture : public osg::StateAttribute
(_border == border);
}
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
void computeSize();
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
unsigned int _size;
};
// forward declare
@@ -959,6 +965,8 @@ class OSG_EXPORT Texture : public osg::StateAttribute
inline GLenum id() const { return _id; }
inline GLenum target() const { return _profile._target; }
inline unsigned int size() const { return _profile._size; }
inline void setTexture(Texture* texture) { _texture = texture; }
inline Texture* getTexture() const { return _texture; }
@@ -1009,7 +1017,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute
void moveToBack(TextureObject* to);
void addToBack(TextureObject* to);
void orphan(TextureObject* to);
unsigned int size() const;
unsigned int size() const { return _profile._size * _numOfTextureObjects; }
bool makeSpace(unsigned int& size);
bool checkConsistency() const;
@@ -1038,8 +1048,14 @@ class OSG_EXPORT Texture : public osg::StateAttribute
unsigned int getContextID() const { return _contextID; }
void setTexturePoolSize(unsigned int size);
unsigned int getTexturePoolSize() const { return _texturePoolSize; }
void setCurrTexturePoolSize(unsigned int size) { _currTexturePoolSize = size; }
unsigned int getCurrTexturePoolSize() const { return _currTexturePoolSize; }
void setMaxTexturePoolSize(unsigned int size);
unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
bool hasSpace(unsigned int size) const { return (_currTexturePoolSize+size)<=_maxTexturePoolSize; }
bool makeSpace(unsigned int size);
TextureObject* generateTextureObject(const Texture* texture, GLenum target);
TextureObject* generateTextureObject(const Texture* texture,
@@ -1060,7 +1076,8 @@ class OSG_EXPORT Texture : public osg::StateAttribute
typedef std::map< TextureProfile, osg::ref_ptr<TextureObjectSet> > TextureSetMap;
unsigned int _contextID;
unsigned int _texturePoolSize;
unsigned int _currTexturePoolSize;
unsigned int _maxTexturePoolSize;
TextureSetMap _textureSetMap;
};

View File

@@ -68,7 +68,7 @@ unsigned int Texture::getMinimumNumberOfTextureObjectsToRetainInCache()
}
#define USE_NEW_TEXTURE_POOL 0
#define USE_NEW_TEXTURE_POOL 1
void Texture::TextureObject::bind()
{
@@ -76,6 +76,11 @@ void Texture::TextureObject::bind()
if (_set) _set->moveToBack(this);
}
void Texture::TextureProfile::computeSize()
{
unsigned int numBitsPerTexel = 32;
_size = (_width * _height * _depth * numBitsPerTexel)/8;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -201,13 +206,6 @@ void Texture::TextureObjectSet::handlePendingOrphandedTextureObjects()
void Texture::TextureObjectSet::flushAllDeletedTextureObjects()
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
handlePendingOrphandedTextureObjects();
}
return;
for(TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
itr != _orphanedTextureObjects.end();
++itr)
@@ -220,15 +218,21 @@ void Texture::TextureObjectSet::flushAllDeletedTextureObjects()
glDeleteTextures( 1L, &id);
}
_numOfTextureObjects -= _orphanedTextureObjects.size();
_orphanedTextureObjects.clear();
// update the TextureObjectManager's running total of current pool size
_parent->setCurrTexturePoolSize( _parent->getCurrTexturePoolSize() - _orphanedTextureObjects.size()*_profile._size );
_orphanedTextureObjects.clear();
}
void Texture::TextureObjectSet::discardAllDeletedTextureObjects()
{
_numOfTextureObjects -= _orphanedTextureObjects.size();
// update the TextureObjectManager's running total of current pool size
_parent->setCurrTexturePoolSize( _parent->getCurrTexturePoolSize() - _orphanedTextureObjects.size()*_profile._size );
// just clear the list as there is nothing else we can do with them when discarding them
_pendingOrphanedTextureObjects.clear();
_orphanedTextureObjects.clear();
}
@@ -239,6 +243,22 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double currentTime, d
flushAllDeletedTextureObjects();
}
bool Texture::TextureObjectSet::makeSpace(unsigned int& size)
{
if (!_orphanedTextureObjects.empty())
{
unsigned int sizeAvailable = _orphanedTextureObjects.size() * _profile._size;
if (size>sizeAvailable) size -= sizeAvailable;
else size = 0;
flushAllDeletedTextureObjects();
}
return size==0;
}
Texture::TextureObject* Texture::TextureObjectSet::takeOrGenerate(Texture* texture)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
@@ -266,8 +286,8 @@ Texture::TextureObject* Texture::TextureObjectSet::takeOrGenerate(Texture* textu
}
// see if we can reuse TextureObject by taking the least recently used active TextureObject
if ((_parent->getTexturePoolSize()!=0) &&
(_numOfTextureObjects > _parent->getTexturePoolSize()) &&
if ((_parent->getMaxTexturePoolSize()!=0) &&
(!_parent->hasSpace(_profile._size)) &&
(_numOfTextureObjects>1) &&
(_head != 0))
{
@@ -306,6 +326,9 @@ Texture::TextureObject* Texture::TextureObjectSet::takeOrGenerate(Texture* textu
to->_set = this;
++_numOfTextureObjects;
// update the current texture pool size
_parent->setCurrTexturePoolSize( _parent->getCurrTexturePoolSize() + _profile._size );
addToBack(to);
osg::notify(osg::NOTICE)<<"Created new TextureObject, _numOfTextureObjects "<<_numOfTextureObjects<<std::endl;
@@ -426,22 +449,35 @@ void Texture::TextureObjectSet::orphan(Texture::TextureObject* to)
#endif
}
unsigned int Texture::TextureObjectSet::size() const
{
osg::notify(osg::NOTICE)<<"Texture::TextureObjectSet::size() Not implemented yet"<<std::endl;
return 0;
}
Texture::TextureObjectManager::TextureObjectManager(unsigned int contextID):
_contextID(contextID),
_texturePoolSize(0)
_currTexturePoolSize(0),
_maxTexturePoolSize(0)
{
}
void Texture::TextureObjectManager::setTexturePoolSize(unsigned int size)
void Texture::TextureObjectManager::setMaxTexturePoolSize(unsigned int size)
{
_texturePoolSize = size;
if (_maxTexturePoolSize == size) return;
if (size>_currTexturePoolSize)
{
osg::notify(osg::NOTICE)<<"Warning: new MaxTexturePoolSize is smaller than current TexturePoolSize"<<std::endl;
}
_maxTexturePoolSize = size;
}
bool Texture::TextureObjectManager::makeSpace(unsigned int size)
{
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end() && size>0;
++itr)
{
if ((*itr).second->makeSpace(size)) return true;
}
return size==0;
}
@@ -477,6 +513,8 @@ void Texture::TextureObjectManager::handlePendingOrphandedTextureObjects()
void Texture::TextureObjectManager::flushAllDeletedTextureObjects()
{
return;
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
++itr)
@@ -1801,13 +1839,20 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
if (!compressed_image)
{
#if 0
glTexImage2D( target, 0, _internalFormat,
inwidth, inheight, _borderWidth,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
data -dataMinusOffset+dataPlusOffset);
#else
glTexSubImage2D( target, 0,
0, 0,
inwidth, inheight,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
data - dataMinusOffset + dataPlusOffset);
#endif
}
else if (extensions->isCompressedTexImage2DSupported())
{
@@ -2277,4 +2322,4 @@ void Texture::Extensions::glGetCompressedTexImage(GLenum target, GLint level, GL
}
}
}
}

View File

@@ -849,7 +849,7 @@ bool SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& mod
osg::State* state = _renderInfo.getState();
if (state->getMaxTexturePoolSize()!=0)
{
osg::Texture::getTextureObjectManager(state->getContextID())->setTexturePoolSize(state->getMaxTexturePoolSize());
osg::Texture::getTextureObjectManager(state->getContextID())->setMaxTexturePoolSize(state->getMaxTexturePoolSize());
}

View File

@@ -706,6 +706,11 @@ BEGIN_OBJECT_REFLECTOR(osg::Texture::TextureObject)
__GLenum__target,
"",
"");
I_Method0(unsigned int, size,
Properties::NON_VIRTUAL,
__unsigned_int__size,
"",
"");
I_Method1(void, setTexture, IN, osg::Texture *, texture,
Properties::NON_VIRTUAL,
__void__setTexture__Texture_P1,
@@ -778,14 +783,34 @@ BEGIN_OBJECT_REFLECTOR(osg::Texture::TextureObjectManager)
__unsigned_int__getContextID,
"",
"");
I_Method1(void, setTexturePoolSize, IN, unsigned int, size,
I_Method1(void, setCurrTexturePoolSize, IN, unsigned int, size,
Properties::NON_VIRTUAL,
__void__setTexturePoolSize__unsigned_int,
__void__setCurrTexturePoolSize__unsigned_int,
"",
"");
I_Method0(unsigned int, getTexturePoolSize,
I_Method0(unsigned int, getCurrTexturePoolSize,
Properties::NON_VIRTUAL,
__unsigned_int__getTexturePoolSize,
__unsigned_int__getCurrTexturePoolSize,
"",
"");
I_Method1(void, setMaxTexturePoolSize, IN, unsigned int, size,
Properties::NON_VIRTUAL,
__void__setMaxTexturePoolSize__unsigned_int,
"",
"");
I_Method0(unsigned int, getMaxTexturePoolSize,
Properties::NON_VIRTUAL,
__unsigned_int__getMaxTexturePoolSize,
"",
"");
I_Method1(bool, hasSpace, IN, unsigned int, size,
Properties::NON_VIRTUAL,
__bool__hasSpace__unsigned_int,
"",
"");
I_Method1(bool, makeSpace, IN, unsigned int, size,
Properties::NON_VIRTUAL,
__bool__makeSpace__unsigned_int,
"",
"");
I_Method2(osg::Texture::TextureObject *, generateTextureObject, IN, const osg::Texture *, texture, IN, GLenum, target,
@@ -826,9 +851,12 @@ BEGIN_OBJECT_REFLECTOR(osg::Texture::TextureObjectManager)
I_SimpleProperty(unsigned int, ContextID,
__unsigned_int__getContextID,
0);
I_SimpleProperty(unsigned int, TexturePoolSize,
__unsigned_int__getTexturePoolSize,
__void__setTexturePoolSize__unsigned_int);
I_SimpleProperty(unsigned int, CurrTexturePoolSize,
__unsigned_int__getCurrTexturePoolSize,
__void__setCurrTexturePoolSize__unsigned_int);
I_SimpleProperty(unsigned int, MaxTexturePoolSize,
__unsigned_int__getMaxTexturePoolSize,
__void__setMaxTexturePoolSize__unsigned_int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osg::Texture::TextureObjectSet)
@@ -883,6 +911,11 @@ BEGIN_OBJECT_REFLECTOR(osg::Texture::TextureObjectSet)
__unsigned_int__size,
"",
"");
I_Method1(bool, makeSpace, IN, unsigned int &, size,
Properties::NON_VIRTUAL,
__bool__makeSpace__unsigned_int_R1,
"",
"");
I_Method0(bool, checkConsistency,
Properties::NON_VIRTUAL,
__bool__checkConsistency,
@@ -911,6 +944,11 @@ BEGIN_VALUE_REFLECTOR(osg::Texture::TextureProfile)
__bool__match__GLenum__GLint__GLenum__GLsizei__GLsizei__GLsizei__GLint,
"",
"");
I_Method0(void, computeSize,
Properties::NON_VIRTUAL,
__void__computeSize,
"",
"");
I_PublicMemberProperty(GLenum, _target);
I_PublicMemberProperty(GLint, _numMipmapLevels);
I_PublicMemberProperty(GLenum, _internalFormat);
@@ -918,6 +956,7 @@ BEGIN_VALUE_REFLECTOR(osg::Texture::TextureProfile)
I_PublicMemberProperty(GLsizei, _height);
I_PublicMemberProperty(GLsizei, _depth);
I_PublicMemberProperty(GLint, _border);
I_PublicMemberProperty(unsigned int, _size);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::ref_ptr< osg::Texture::TextureObject >)