From Michael Platings, To address performance bottleneck that occurs when using large number of uniforms introduced a name to uniqued ID scheme for Uniforms so comparisons can be done on a uint rather than a string.
This commit is contained in:
parent
4b4e02e45b
commit
cdfbb7a753
@ -147,8 +147,9 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
|||||||
GLenum _type;
|
GLenum _type;
|
||||||
GLint _size;
|
GLint _size;
|
||||||
};
|
};
|
||||||
|
typedef std::map< unsigned int, ActiveVarInfo > ActiveUniformMap;
|
||||||
typedef std::map< std::string, ActiveVarInfo > ActiveVarInfoMap;
|
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;
|
const ActiveVarInfoMap& getActiveAttribs(unsigned int contextID) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -189,7 +190,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
|||||||
|
|
||||||
inline void apply(const Uniform& uniform) const
|
inline void apply(const Uniform& uniform) const
|
||||||
{
|
{
|
||||||
GLint location = getUniformLocation(uniform.getName());
|
GLint location = getUniformLocation(uniform.getNameID());
|
||||||
if (location>=0)
|
if (location>=0)
|
||||||
{
|
{
|
||||||
if ((unsigned int)location>=_lastAppliedUniformList.size()) _lastAppliedUniformList.resize(location+1);
|
if ((unsigned int)location>=_lastAppliedUniformList.size()) _lastAppliedUniformList.resize(location+1);
|
||||||
@ -211,10 +212,10 @@ 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;}
|
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; }
|
||||||
inline GLint getAttribLocation( const std::string& name ) const { ActiveVarInfoMap::const_iterator itr = _attribInfoMap.find(name); return (itr!=_attribInfoMap.end()) ? itr->second._location : -1; }
|
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)
|
inline void addShaderToAttach(Shader *shader)
|
||||||
@ -243,7 +244,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
|||||||
bool _isLinked;
|
bool _isLinked;
|
||||||
const unsigned int _contextID;
|
const unsigned int _contextID;
|
||||||
|
|
||||||
ActiveVarInfoMap _uniformInfoMap;
|
ActiveUniformMap _uniformInfoMap;
|
||||||
ActiveVarInfoMap _attribInfoMap;
|
ActiveVarInfoMap _attribInfoMap;
|
||||||
|
|
||||||
typedef std::pair<osg::ref_ptr<const osg::Uniform>, unsigned int> UniformModifiedCountPair;
|
typedef std::pair<osg::ref_ptr<const osg::Uniform>, unsigned int> UniformModifiedCountPair;
|
||||||
|
@ -1253,7 +1253,7 @@ class OSG_EXPORT State : public Referenced, public Observer
|
|||||||
}
|
}
|
||||||
inline const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; }
|
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; }
|
||||||
inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getAttribLocation(name) : -1; }
|
inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getAttribLocation(name) : -1; }
|
||||||
|
|
||||||
typedef std::pair<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
|
typedef std::pair<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
|
||||||
|
@ -268,6 +268,9 @@ class OSG_EXPORT Uniform : public Object
|
|||||||
/** Return the internal data array type corresponding to a GLSL type */
|
/** Return the internal data array type corresponding to a GLSL type */
|
||||||
static GLenum getInternalArrayType( Type t );
|
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 */
|
/** convenient scalar (non-array) constructors w/ assignment */
|
||||||
explicit Uniform( const char* name, float f );
|
explicit Uniform( const char* name, float f );
|
||||||
explicit Uniform( const char* name, int i );
|
explicit Uniform( const char* name, int i );
|
||||||
@ -472,6 +475,8 @@ class OSG_EXPORT Uniform : public Object
|
|||||||
inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; }
|
inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; }
|
||||||
inline unsigned int getModifiedCount() const { return _modifiedCount; }
|
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;
|
void apply(const GL2Extensions* ext, GLint location) const;
|
||||||
|
|
||||||
@ -493,6 +498,8 @@ class OSG_EXPORT Uniform : public Object
|
|||||||
|
|
||||||
Type _type;
|
Type _type;
|
||||||
unsigned int _numElements;
|
unsigned int _numElements;
|
||||||
|
unsigned int _nameID;
|
||||||
|
|
||||||
|
|
||||||
// The internal data for osg::Uniforms are stored as an array of
|
// The internal data for osg::Uniforms are stored as an array of
|
||||||
// getInternalArrayType() of length getInternalArrayNumElements().
|
// getInternalArrayType() of length getInternalArrayNumElements().
|
||||||
|
@ -452,7 +452,7 @@ bool Program::getGlProgramInfoLog(unsigned int contextID, std::string& log) cons
|
|||||||
return getPCP( contextID )->getInfoLog( log );
|
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();
|
return getPCP( contextID )->getActiveUniforms();
|
||||||
}
|
}
|
||||||
@ -609,7 +609,7 @@ void Program::PerContextProgram::linkProgram(osg::State& state)
|
|||||||
|
|
||||||
if( loc != -1 )
|
if( loc != -1 )
|
||||||
{
|
{
|
||||||
_uniformInfoMap[reinterpret_cast<char*>(name)] = ActiveVarInfo(loc,type,size);
|
_uniformInfoMap[Uniform::getNameID(reinterpret_cast<const char*>(name))] = ActiveVarInfo(loc,type,size);
|
||||||
|
|
||||||
OSG_INFO << "\tUniform \"" << name << "\""
|
OSG_INFO << "\tUniform \"" << name << "\""
|
||||||
<< " loc="<< loc
|
<< " loc="<< loc
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <osg/Program>
|
#include <osg/Program>
|
||||||
#include <osg/StateSet>
|
#include <osg/StateSet>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
@ -30,13 +31,13 @@ using namespace osg;
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Uniform::Uniform() :
|
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 ) :
|
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);
|
setName(name);
|
||||||
setNumElements(numElements);
|
setNumElements(numElements);
|
||||||
@ -88,6 +89,7 @@ void Uniform::setName( const std::string& name )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_name = name;
|
_name = name;
|
||||||
|
_nameID = getNameID(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uniform::setNumElements( unsigned int numElements )
|
void Uniform::setNumElements( unsigned int numElements )
|
||||||
@ -255,6 +257,7 @@ void Uniform::copyData(const Uniform& rhs)
|
|||||||
{
|
{
|
||||||
// caller must ensure that _type==rhs._type
|
// caller must ensure that _type==rhs._type
|
||||||
_numElements = rhs._numElements;
|
_numElements = rhs._numElements;
|
||||||
|
_nameID = rhs._nameID;
|
||||||
if (rhs._floatArray.valid() || rhs._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
|
if (rhs._floatArray.valid() || rhs._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
|
||||||
if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
|
if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
|
||||||
if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray;
|
if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray;
|
||||||
@ -601,6 +604,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
|
// value constructors for single-element (ie: non-array) uniforms
|
||||||
|
|
||||||
@ -1388,6 +1409,11 @@ bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2, bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int Uniform::getNameID() const
|
||||||
|
{
|
||||||
|
return _nameID;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Uniform::apply(const GL2Extensions* ext, GLint location) const
|
void Uniform::apply(const GL2Extensions* ext, GLint location) const
|
||||||
|
Loading…
Reference in New Issue
Block a user