Introduced memory pool size management
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 >)
|
||||
|
||||
Reference in New Issue
Block a user