// IMPLEMENTATION
+std::set< std::string > Program::mExternalUniformNames;
+
Program* Program::New( const Integration::ResourceId& resourceId, Integration::ShaderData* shaderData, Context& context )
{
size_t shaderHash = shaderData->GetHashValue();
return mAttribLocations[type];
}
-unsigned int Program::RegisterUniform( const std::string& name )
+unsigned int Program::RegisterExternalUniform( const std::string& name )
+{
+ // insert the name in the table to keep it alive as long as this program exists
+ // we rely on C++ strings COW behaviour to keep the char* alive.
+ // TODO In C++ 11 this is no longer the case so this code needs changing if we upgrade
+ mExternalUniformNames.insert( name );
+ return RegisterUniform( name.c_str() );
+}
+
+unsigned int Program::RegisterUniform( const char* name )
{
unsigned int index = 0;
// find the value from cache
- for( ;index < mUniformLocations.size(); ++index )
+ for( ;index < mCustomUniformLocations.size(); ++index )
{
- if( mUniformLocations[ index ].first == name )
+ if( !strcmp( mCustomUniformLocations[ index ].first, name ) )
{
- // name found so return index
- return index;
+ // name found so return index plus built in index count
+ return index + UNIFORM_TYPE_LAST;
}
}
// if we get here, index is one past end so push back the new name
- mUniformLocations.push_back( std::make_pair( name, UNIFORM_NOT_QUERIED ) );
- return index;
+ mCustomUniformLocations.push_back( std::make_pair( name, UNIFORM_NOT_QUERIED ) );
+ return index + UNIFORM_TYPE_LAST; // remember to add the count of the built in ones
}
GLint Program::GetUniformLocation( unsigned int uniformIndex )
{
- // debug check that index is within name cache
- DALI_ASSERT_DEBUG( mUniformLocations.size() > uniformIndex );
-
- // check if we have already queried the location of the uniform
- GLint location = mUniformLocations[ uniformIndex ].second;
+ GLint location = UNIFORM_NOT_QUERIED;
+ // is it built in
+ if( uniformIndex < UNIFORM_TYPE_LAST )
+ {
+ // check if we have already queried the location of the uniform
+ location = mBuiltinUniformLocations[ uniformIndex ];
+ if( location == UNIFORM_NOT_QUERIED )
+ {
+ LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mBuiltinUniformLocations[ uniformIndex ], gStdUniforms[ uniformIndex ] );
+ location = CHECK_GL( mContext, mGlAbstraction.GetUniformLocation( mProgramId, gStdUniforms[ uniformIndex ] ) );
- if( location == UNIFORM_NOT_QUERIED )
+ mBuiltinUniformLocations[ uniformIndex ] = location;
+ }
+ }
+ else
{
- LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mUniformLocations[ uniformIndex ].first.c_str(), mUniformLocations[ uniformIndex ].second );
- location = CHECK_GL( mContext, mGlAbstraction.GetUniformLocation( mProgramId, mUniformLocations[ uniformIndex ].first.c_str() ) );
+ // translate the index to custom locations vector
+ unsigned int customIndex = uniformIndex - UNIFORM_TYPE_LAST;
+ if( customIndex < mCustomUniformLocations.size() ) // custom uniform
+ {
+ // check if we have already queried the location of the uniform
+ location = mCustomUniformLocations[ customIndex ].second;
+ if( location == UNIFORM_NOT_QUERIED )
+ {
+ LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mCustomUniformLocations[ customIndex ].first, mCustomUniformLocations[ customIndex ].second );
+ location = CHECK_GL( mContext, mGlAbstraction.GetUniformLocation( mProgramId, mCustomUniformLocations[ customIndex ].first ) );
- mUniformLocations[ uniformIndex ].second = location;
+ mCustomUniformLocations[ customIndex ].second = location;
+ }
+ }
}
return location;
mProgramId( 0 ),
mProgramData(shaderData)
{
- // reserve space for standard uniforms
- mUniformLocations.reserve( UNIFORM_TYPE_LAST );
- // reset built in uniform names in cache
- for( int i = 0; i < UNIFORM_TYPE_LAST; ++i )
- {
- RegisterUniform( gStdUniforms[ i ] );
- }
// reset values
ResetAttribsUniforms();
}
// reset all gl uniform locations
- for( unsigned int i = 0; i < mUniformLocations.size(); ++i )
+ for( unsigned int i = 0; i < UNIFORM_TYPE_LAST; ++i )
+ {
+ mBuiltinUniformLocations[ i ] = UNIFORM_NOT_QUERIED;
+ }
+ for( unsigned int i = 0; i < mCustomUniformLocations.size(); ++i )
{
- // reset gl program locations and names
- mUniformLocations[ i ].second = UNIFORM_NOT_QUERIED;
+ mCustomUniformLocations[ i ].second = UNIFORM_NOT_QUERIED;
}
// reset uniform cache
* @param [in] name uniform name
* @return the index of the uniform name in local cache
*/
- unsigned int RegisterUniform( const std::string& name );
+ unsigned int RegisterExternalUniform( const std::string& name );
+
+ /**
+ * Register a uniform name in our local cache
+ * @param [in] name uniform name
+ * @return the index of the uniform name in local cache
+ */
+ unsigned int RegisterUniform( const char* name );
/**
* Gets the location of a pre-registered uniform.
GLuint mProgramId; ///< GL identifier for program
Integration::ShaderData* mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
- // location caches
+ // uniform location caches
GLint mAttribLocations[ ATTRIB_TYPE_LAST ]; ///< attribute location cache
- std::vector< std::pair< std::string, GLint > > mUniformLocations; ///< uniform location cache
+ GLint mBuiltinUniformLocations[ UNIFORM_TYPE_LAST ]; ///< uniform location cache for built in uniforms
+ std::vector< std::pair< const char *, GLint > > mCustomUniformLocations; ///< uniform location cache for custom uniforms
+ static std::set< std::string > mExternalUniformNames; /// < names for externally specified uniforms, set to avoid duplicates
// uniform value caching
GLint mUniformCacheInt[ MAX_UNIFORM_CACHE_SIZE ]; ///< Value cache for uniforms of single int