diff --git a/include/osg/Texture b/include/osg/Texture index a9503ef02..7bbb0782d 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -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 > TextureSetMap; unsigned int _contextID; - unsigned int _texturePoolSize; + unsigned int _currTexturePoolSize; + unsigned int _maxTexturePoolSize; TextureSetMap _textureSetMap; }; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 0a591865c..6c746e19e 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -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 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 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<_currTexturePoolSize) + { + osg::notify(osg::NOTICE)<<"Warning: new MaxTexturePoolSize is smaller than current TexturePoolSize"<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 } } -} \ No newline at end of file +} diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 5499177e0..b6abccd33 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -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()); } diff --git a/src/osgWrappers/osg/Texture.cpp b/src/osgWrappers/osg/Texture.cpp index 493d5dc33..948eaa9a3 100644 --- a/src/osgWrappers/osg/Texture.cpp +++ b/src/osgWrappers/osg/Texture.cpp @@ -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 >)