2.8 branch: Uniform lookup by cached name ID. Trunk revisions r11952, r11998, and r12074.

This commit is contained in:
Paul MARTZ
2011-05-02 22:13:01 +00:00
parent 288fb20eb6
commit 2f7167d011
5 changed files with 65 additions and 12 deletions

View File

@@ -142,8 +142,9 @@ class OSG_EXPORT Program : public osg::StateAttribute
GLenum _type;
GLint _size;
};
typedef std::map< unsigned int, ActiveVarInfo > ActiveUniformMap;
typedef std::map< std::string, ActiveVarInfo > ActiveVarInfoMap;
const ActiveVarInfoMap& getActiveUniforms(unsigned int contextID) const;
const ActiveUniformMap& getActiveUniforms(unsigned int contextID) const;
const ActiveVarInfoMap& getActiveAttribs(unsigned int contextID) const;
public:
@@ -184,7 +185,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
inline void apply(const Uniform& uniform) const
{
GLint location = getUniformLocation(uniform.getName());
GLint location = getUniformLocation(uniform.getNameID());
if (location>=0)
{
if ((unsigned int)location>=_lastAppliedUniformList.size()) _lastAppliedUniformList.resize(location+1);
@@ -206,10 +207,21 @@ class OSG_EXPORT Program : public osg::StateAttribute
}
}
const ActiveVarInfoMap& getActiveUniforms() const {return _uniformInfoMap;}
const ActiveUniformMap& getActiveUniforms() const {return _uniformInfoMap;}
const ActiveVarInfoMap& getActiveAttribs() const {return _attribInfoMap;}
inline GLint getUniformLocation( const std::string& name ) const { ActiveVarInfoMap::const_iterator itr = _uniformInfoMap.find(name); return (itr!=_uniformInfoMap.end()) ? itr->second._location : -1; }
inline GLint getUniformLocation( unsigned int uniformNameID ) const { ActiveUniformMap::const_iterator itr = _uniformInfoMap.find(uniformNameID); return (itr!=_uniformInfoMap.end()) ? itr->second._location : -1; }
/**
* Alternative version of getUniformLocation( unsigned int uniformNameID )
* retrofited into OSG for backward compatibility with osgCal,
* after uniform ids were refactored from std::strings to GLints in OSG version 2.9.10.
*
* Drawbacks: This method is not particularly fast. It has to access mutexed static
* map of uniform ids. So don't overuse it or your app performance will suffer.
*/
inline GLint getUniformLocation( const std::string & uniformName ) const { return getUniformLocation( Uniform::getNameID( uniformName ) ); }
inline GLint getAttribLocation( const std::string& name ) const { ActiveVarInfoMap::const_iterator itr = _attribInfoMap.find(name); return (itr!=_attribInfoMap.end()) ? itr->second._location : -1; }
inline void addShaderToAttach(Shader *shader)
@@ -238,7 +250,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
bool _isLinked;
const unsigned int _contextID;
ActiveVarInfoMap _uniformInfoMap;
ActiveUniformMap _uniformInfoMap;
ActiveVarInfoMap _attribInfoMap;
typedef std::pair<osg::ref_ptr<const osg::Uniform>, unsigned int> UniformModifiedCountPair;

View File

@@ -975,7 +975,16 @@ class OSG_EXPORT State : public Referenced, public Observer
}
inline const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; }
inline GLint getUniformLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(name) : -1; }
inline GLint getUniformLocation( unsigned int uniformNameID ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformNameID) : -1; }
/**
* Alternative version of getUniformLocation( unsigned int uniformNameID )
* retrofited into OSG for backward compatibility with osgCal,
* after uniform ids were refactored from std::strings to GLints in OSG version 2.9.10.
*
* Drawbacks: This method is not particularly fast. It has to access mutexed static
* map of uniform ids. So don't overuse it or your app performance will suffer.
*/
inline GLint getUniformLocation( const std::string & uniformName ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformName) : -1; }
inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getAttribLocation(name) : -1; }

View File

@@ -259,6 +259,9 @@ class OSG_EXPORT Uniform : public Object
/** Return the internal data array type corresponding to a GLSL type */
static GLenum getInternalArrayType( Type t );
/** Return the number that the name maps to uniquely */
static unsigned int getNameID(const std::string& name);
/** convenient scalar (non-array) constructors w/ assignment */
explicit Uniform( const char* name, float f );
explicit Uniform( const char* name, int i );
@@ -463,6 +466,8 @@ class OSG_EXPORT Uniform : public Object
inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; }
inline unsigned int getModifiedCount() const { return _modifiedCount; }
/** Get the number that the Uniform's name maps to uniquely */
unsigned int getNameID() const;
void apply(const GL2Extensions* ext, GLint location) const;
@@ -484,6 +489,8 @@ class OSG_EXPORT Uniform : public Object
Type _type;
unsigned int _numElements;
unsigned int _nameID;
// The internal data for osg::Uniforms are stored as an array of
// getInternalArrayType() of length getInternalArrayNumElements().

View File

@@ -394,7 +394,7 @@ bool Program::getGlProgramInfoLog(unsigned int contextID, std::string& log) cons
return getPCP( contextID )->getInfoLog( log );
}
const Program::ActiveVarInfoMap& Program::getActiveUniforms(unsigned int contextID) const
const Program::ActiveUniformMap& Program::getActiveUniforms(unsigned int contextID) const
{
return getPCP( contextID )->getActiveUniforms();
}
@@ -532,10 +532,9 @@ void Program::PerContextProgram::linkProgram()
if( loc != -1 )
{
_uniformInfoMap[name] = ActiveVarInfo(loc,type,size);
_uniformInfoMap[Uniform::getNameID(reinterpret_cast<const char*>(name))] = ActiveVarInfo(loc,type,size);
osg::notify(osg::INFO)
<< "\tUniform \"" << name << "\""
OSG_INFO << "\tUniform \"" << name << "\""
<< " loc="<< loc
<< " size="<< size
<< " type=" << Uniform::getTypename((Uniform::Type)type)

View File

@@ -21,6 +21,7 @@
#include <osg/Program>
#include <osg/StateSet>
#include <limits.h>
#include <algorithm>
using namespace osg;
@@ -30,13 +31,13 @@ using namespace osg;
///////////////////////////////////////////////////////////////////////////
Uniform::Uniform() :
_type(UNDEFINED), _numElements(0), _modifiedCount(0)
_type(UNDEFINED), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
{
}
Uniform::Uniform( Type type, const std::string& name, int numElements ) :
_type(type), _numElements(0), _modifiedCount(0)
_type(type), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
{
setName(name);
setNumElements(numElements);
@@ -88,6 +89,7 @@ void Uniform::setName( const std::string& name )
return;
}
_name = name;
_nameID = getNameID(name);
}
void Uniform::setNumElements( unsigned int numElements )
@@ -255,6 +257,7 @@ void Uniform::copyData(const Uniform& rhs)
{
// caller must ensure that _type==rhs._type
_numElements = rhs._numElements;
_nameID = rhs._nameID;
if (rhs._floatArray.valid() || rhs._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray;
@@ -602,6 +605,24 @@ GLenum Uniform::getInternalArrayType( Type t )
}
unsigned int Uniform::getNameID(const std::string& name)
{
typedef std::map<std::string, unsigned int> UniformNameIDMap;
static OpenThreads::Mutex s_mutex_uniformNameIDMap;
static UniformNameIDMap s_uniformNameIDMap;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_uniformNameIDMap);
UniformNameIDMap::iterator it = s_uniformNameIDMap.find(name);
if (it != s_uniformNameIDMap.end())
{
return it->second;
}
unsigned int id = s_uniformNameIDMap.size();
s_uniformNameIDMap.insert(UniformNameIDMap::value_type(name, id));
return id;
}
///////////////////////////////////////////////////////////////////////////
// value constructors for single-element (ie: non-array) uniforms
@@ -1389,6 +1410,11 @@ bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2, bool
return true;
}
unsigned int Uniform::getNameID() const
{
return _nameID;
}
///////////////////////////////////////////////////////////////////////////
void Uniform::apply(const GL2Extensions* ext, GLint location) const