Added support for unref image data after apply in the osg::Texture*

classes.  Only unref's after all graphics context have been applied.
This commit is contained in:
Robert Osfield 2003-04-07 12:51:00 +00:00
parent 0df1b28672
commit 9f0fa75484
8 changed files with 102 additions and 5 deletions

View File

@ -159,6 +159,14 @@ class SG_EXPORT Texture : public osg::StateAttribute
/** Get the hint of whether to use hardware mip map generation where available.*/
inline bool getUseHardwareMipMapGeneration() const { return _useHardwareMipMapGeneration; }
/** Set the automatic unreference of image data after the texture has been set up in apply, on (true) or off (false).
* If the image data is only referened by this Texture then the image data will be autoamtically deleted.*/
inline void setUnRefImageDataAfterApply(bool flag) { _unrefImageDataAfterApply = flag; }
/** Get the automatic unreference of image data after the texture has been set up in apply.*/
inline bool getUnRefImageDataAfterApply() const { return _unrefImageDataAfterApply; }
enum InternalFormatMode {
USE_IMAGE_DATA_FORMAT,
USE_USER_DEFINED_FORMAT,
@ -333,6 +341,7 @@ class SG_EXPORT Texture : public osg::StateAttribute
FilterMode _mag_filter;
float _maxAnisotropy;
bool _useHardwareMipMapGeneration;
bool _unrefImageDataAfterApply;
Vec4 _borderColor;

View File

@ -155,7 +155,7 @@ class SG_EXPORT TextureCubeMap : public Texture
virtual void computeInternalFormat() const;
mutable ref_ptr<Image> _images[6];
ref_ptr<Image> _images[6];
// subloaded images can have different texture and image sizes.
mutable GLsizei _textureWidth, _textureHeight;

View File

@ -68,7 +68,8 @@ Texture::Texture():
_min_filter(LINEAR_MIPMAP_LINEAR), // trilinear
_mag_filter(LINEAR),
_maxAnisotropy(1.0f),
_useHardwareMipMapGeneration(false),
_useHardwareMipMapGeneration(true),
_unrefImageDataAfterApply(false),
_borderColor(0.0, 0.0, 0.0, 0.0),
_internalFormatMode(USE_IMAGE_DATA_FORMAT),
_internalFormat(0)
@ -84,6 +85,7 @@ Texture::Texture(const Texture& text,const CopyOp& copyop):
_mag_filter(text._mag_filter),
_maxAnisotropy(text._maxAnisotropy),
_useHardwareMipMapGeneration(text._useHardwareMipMapGeneration),
_unrefImageDataAfterApply(text._unrefImageDataAfterApply),
_borderColor(text._borderColor),
_internalFormatMode(text._internalFormatMode),
_internalFormat(text._internalFormat)

View File

@ -144,6 +144,20 @@ void Texture1D::apply(State& state) const
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture1D* non_const_this = const_cast<Texture1D*>(this);
non_const_this->_image = 0;
}
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures

View File

@ -147,6 +147,22 @@ void Texture2D::apply(State& state) const
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
{
// only unref image once all the graphics contexts has been set up.
int numLeftToBind=0;
for(int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture2D* non_const_this = const_cast<Texture2D*>(this);
non_const_this->_image = 0;
}
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!

View File

@ -161,6 +161,21 @@ void Texture3D::apply(State& state) const
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture3D* non_const_this = const_cast<Texture3D*>(this);
non_const_this->_image = 0;
}
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!

View File

@ -221,7 +221,7 @@ void TextureCubeMap::apply(State& state) const
{
for (int n=0; n<6; n++)
{
osg::Image* image = _images[n].get();
const osg::Image* image = _images[n].get();
if (image && getModifiedTag((Face)n,contextID) != image->getModifiedTag())
{
applyTexImage2D_subload( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMimpmapLevels);
@ -264,14 +264,37 @@ void TextureCubeMap::apply(State& state) const
for (int n=0; n<6; n++)
{
osg::Image* image = _images[n].get();
const osg::Image* image = _images[n].get();
if (image)
{
applyTexImage2D_load( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMimpmapLevels);
getModifiedTag((Face)n,contextID) = image->getModifiedTag();
}
}
if (_unrefImageDataAfterApply)
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
TextureCubeMap* non_const_this = const_cast<TextureCubeMap*>(this);
for (int n=0; n<6; n++)
{
non_const_this->_images[n] = 0;
}
}
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!

View File

@ -91,7 +91,7 @@ bool Texture_readLocalData(Object& obj, Input& fr)
fr +=2 ;
iteratorAdvanced = true;
}
else if (fr[1].matchWord("TRUE"))
else if (fr[1].matchWord("FALSE"))
{
texture.setUseHardwareMipMapGeneration(false);
fr +=2 ;
@ -99,6 +99,23 @@ bool Texture_readLocalData(Object& obj, Input& fr)
}
}
if (fr[0].matchWord("unRefImageDataAfterApply"))
{
if (fr[1].matchWord("TRUE"))
{
texture.setUnRefImageDataAfterApply(true);
fr +=2 ;
iteratorAdvanced = true;
}
else if (fr[1].matchWord("FALSE"))
{
texture.setUnRefImageDataAfterApply(false);
fr +=2 ;
iteratorAdvanced = true;
}
}
Texture::InternalFormatMode mode;
if (fr[0].matchWord("internalFormatMode") && Texture_matchInternalFormatModeStr(fr[1].getStr(),mode))
{
@ -135,6 +152,7 @@ bool Texture_writeLocalData(const Object& obj, Output& fw)
fw.indent() << "maxAnisotropy " << texture.getMaxAnisotropy() << std::endl;
fw.indent() << "useHardwareMipMapGeneration "<< (texture.getUseHardwareMipMapGeneration()?"TRUE":"FALSE") << std::endl;
fw.indent() << "unRefImageDataAfterApply "<< (texture.getUnRefImageDataAfterApply()?"TRUE":"FALSE") << std::endl;
fw.indent() << "internalFormatMode " << Texture_getInternalFormatModeStr(texture.getInternalFormatMode()) << std::endl;