Added OPTIMIZER_TEXTURE_SETTINGS pass to Optimizer, which enables

unref image data after apply, client storage hint.
This commit is contained in:
Robert Osfield
2004-07-12 13:20:18 +00:00
parent 3e5c491f54
commit 6fd4677868
3 changed files with 146 additions and 16 deletions

View File

@@ -49,12 +49,14 @@ class OSGUTIL_EXPORT Optimizer
COPY_SHARED_NODES = 0x080,
TRISTRIP_GEOMETRY = 0x100,
TESSELATE_GEOMETRY = 0x200,
OPTIMIZE_TEXTURE_SETTINGS = 0x400,
DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
REMOVE_REDUNDANT_NODES |
COMBINE_ADJACENT_LODS |
SHARE_DUPLICATE_STATE |
MERGE_GEOMETRY |
CHECK_GEOMETRY,
CHECK_GEOMETRY |
OPTIMIZE_TEXTURE_SETTINGS,
ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
REMOVE_REDUNDANT_NODES |
COMBINE_ADJACENT_LODS |
@@ -63,7 +65,8 @@ class OSGUTIL_EXPORT Optimizer
CHECK_GEOMETRY |
SPATIALIZE_GROUPS |
COPY_SHARED_NODES |
TRISTRIP_GEOMETRY
TRISTRIP_GEOMETRY |
OPTIMIZE_TEXTURE_SETTINGS
};
/** reset internal data to initial state - the getPrimissableOptionsMap is cleared.*/
@@ -408,6 +411,43 @@ class OSGUTIL_EXPORT Optimizer
Optimizer* _optimizer;
};
/** For all textures apply settings.*/
class OSGUTIL_EXPORT TextureVisitor : public osg::NodeVisitor
{
public:
TextureVisitor(bool changeAutoUnRef, bool valueAutoUnRef,
bool changeClientImageStorage, bool valueClientImageStorage,
bool changeAnisotropy, float valueAnisotropy,
Optimizer* optimizer=0):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_optimizer(optimizer),
_changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef),
_changeClientImageStorage(changeClientImageStorage), _valueClientImageStorage(valueClientImageStorage),
_changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy) {}
virtual void apply(osg::Geode& node);
virtual void apply(osg::Node& node);
void apply(osg::StateSet& stateset);
void apply(osg::Texture& texture);
inline bool isOperationPermissableForObject(const osg::Object* object) const
{
return _optimizer ? _optimizer->isOperationPermissableForObject(object,OPTIMIZE_TEXTURE_SETTINGS) : true;
}
Optimizer* _optimizer;
bool _changeAutoUnRef, _valueAutoUnRef;
bool _changeClientImageStorage, _valueClientImageStorage;
bool _changeAnisotropy, _valueAnisotropy;
};
};
}

View File

@@ -242,21 +242,14 @@ public:
{
// search for the existance of any texture object attributes
bool foundTextureState = false;
osg::StateSet::TextureAttributeList& tal = stateset->getTextureAttributeList();
for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin();
itr!=tal.end() && !foundTextureState;
++itr)
for(unsigned int i=0;i<stateset->getTextureAttributeList().size();++i)
{
osg::StateSet::AttributeList& al = *itr;
if (al.count(osg::StateAttribute::TEXTURE)==1)
osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
if (texture)
{
texture->setUnRefImageDataAfterApply(_unrefImageOnApply);
texture->setClientStorageHint(_clientStorageHint);
foundTextureState = true;
osg::Texture* texture = dynamic_cast<osg::Texture*>(al[osg::StateAttribute::TEXTURE].first.get());
if (texture)
{
texture->setUnRefImageDataAfterApply(_unrefImageOnApply);
texture->setClientStorageHint(_clientStorageHint);
}
}
}

View File

@@ -24,6 +24,7 @@
#include <osg/OccluderNode>
#include <osg/Sequence>
#include <osg/Switch>
#include <osg/Texture>
#include <osgUtil/TransformAttributeFunctor>
#include <osgUtil/TriStripVisitor>
@@ -56,7 +57,7 @@ void Optimizer::reset()
_permissableOptimizationsMap.clear();
}
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY");
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS");
void Optimizer::optimize(osg::Node* node)
{
@@ -98,6 +99,11 @@ void Optimizer::optimize(osg::Node* node)
if(str.find("~TRISTRIP_GEOMETRY")!=std::string::npos) options ^= TRISTRIP_GEOMETRY;
else if(str.find("TRISTRIP_GEOMETRY")!=std::string::npos) options |= TRISTRIP_GEOMETRY;
if(str.find("~OPTIMIZE_TEXTURE_SETTINGS")!=std::string::npos) options ^= OPTIMIZE_TEXTURE_SETTINGS;
else if(str.find("OPTIMIZE_TEXTURE_SETTINGS")!=std::string::npos) options |= OPTIMIZE_TEXTURE_SETTINGS;
}
else
{
@@ -127,6 +133,17 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
clv.combineLODs();
}
if (options & OPTIMIZE_TEXTURE_SETTINGS)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing OPTIMIZE_TEXTURE_SETTINGS"<<std::endl;
TextureVisitor tv(true,true, // unref image
true,true, // client storage
false,1.0, // anisotropic filtering
this );
node->accept(tv);
}
if (options & SHARE_DUPLICATE_STATE)
{
osg::notify(osg::INFO)<<"Optimizer::optimize() doing SHARE_DUPLICATE_STATE"<<std::endl;
@@ -215,7 +232,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
node->accept(tsv);
tsv.stripify();
}
}
@@ -2151,3 +2168,83 @@ void Optimizer::CopySharedSubgraphsVisitor::copySharedNodes()
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
//
// Set the attributes of textures up.
//
void Optimizer::TextureVisitor::apply(osg::Node& node)
{
osg::StateSet* ss = node.getStateSet();
if (ss &&
isOperationPermissableForObject(&node) &&
isOperationPermissableForObject(ss))
{
apply(*ss);
}
traverse(node);
}
void Optimizer::TextureVisitor::apply(osg::Geode& geode)
{
if (!isOperationPermissableForObject(&geode)) return;
osg::StateSet* ss = geode.getStateSet();
if (ss && isOperationPermissableForObject(ss))
{
apply(*ss);
}
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
if (drawable)
{
ss = drawable->getStateSet();
if (ss &&
isOperationPermissableForObject(drawable) &&
isOperationPermissableForObject(ss))
{
apply(*ss);
}
}
}
}
void Optimizer::TextureVisitor::apply(osg::StateSet& stateset)
{
for(unsigned int i=0;i<stateset.getTextureAttributeList().size();++i)
{
osg::StateAttribute* sa = stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE);
osg::Texture* texture = dynamic_cast<osg::Texture*>(sa);
if (texture && isOperationPermissableForObject(texture))
{
apply(*texture);
}
}
}
void Optimizer::TextureVisitor::apply(osg::Texture& texture)
{
if (_changeAutoUnRef)
{
texture.setUnRefImageDataAfterApply(_valueAutoUnRef);
}
if (_changeClientImageStorage)
{
texture.setClientStorageHint(_valueClientImageStorage);
}
if (_changeAnisotropy)
{
texture.setMaxAnisotropy(_valueAnisotropy);
}
}