X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Fshaders%2Fprogram.cpp;h=38370dc81c6448c7402078e233e8ff1ebed56908;hb=e88e652e1adc2de3ace849c3bafbf6c75e5632ba;hp=c6b605cc6c4f751eb14c3431edf258a8410feab5;hpb=0c54941cf8698af1f9e02a212bf6de675c04ba34;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp index c6b605c..38370dc 100644 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -19,15 +19,18 @@ #include // EXTERNAL INCLUDES -#include #include // INTERNAL INCLUDES #include +#include #include -#include #include -#include +#include +#include +#include +#include +#include namespace { @@ -76,11 +79,7 @@ namespace const char* gStdAttribs[ Program::ATTRIB_TYPE_LAST ] = { "aPosition", // ATTRIB_POSITION - "aNormal", // ATTRIB_NORMAL "aTexCoord", // ATTRIB_TEXCOORD - "aColor", // ATTRIB_COLOR - "aBoneWeights", // ATTRIB_BONE_WEIGHTS - "aBoneIndices" // ATTRIB_BONE_INDICES }; const char* gStdUniforms[ Program::UNIFORM_TYPE_LAST ] = @@ -92,46 +91,28 @@ const char* gStdUniforms[ Program::UNIFORM_TYPE_LAST ] = "uViewMatrix", // UNIFORM_VIEW_MATRIX, "uNormalMatrix", // UNIFORM_NORMAL_MATRIX "uColor", // UNIFORM_COLOR - "uCustomTextureCoords", // UNIFORM_CUSTOM_TEXTURE_COORDS "sTexture", // UNIFORM_SAMPLER "sTextureRect", // UNIFORM_SAMPLER_RECT "sEffect", // UNIFORM_EFFECT_SAMPLER - "sEffectRect", // UNIFORM_EFFECT_SAMPLER_RECT - "uTimeDelta", // UNIFORM_TIME_DELTA - "sOpacityTexture", // UNIFORM_SAMPLER_OPACITY - "sNormalMapTexture", // UNIFORM_SAMPLER_NORMAL_MAP - "uTextColor", // UNIFORM_TEXT_COLOR - "uSmoothing", // UNIFORM_SMOOTHING - "uOutline", // UNIFORM_OUTLINE - "uOutlineColor", // UNIFORM_OUTLINE_COLOR - "uGlow", // UNIFORM_GLOW - "uGlowColor", // UNIFORM_GLOW_COLOR - "uShadow", // UNIFORM_SHADOW - "uShadowColor", // UNIFORM_SHADOW_COLOR - "uShadowSmoothing", // UNIFORM_SHADOW_SMOOTHING - "uGradientColor", // UNIFORM_GRADIENT_COLOR - "uGradientLine", // UNIFORM_GRADIENT_LINE - "uInvTextSize" // UNIFORM_INVERSE_TEXT_SIZE + "uSize" // UNIFORM_SIZE }; } // namespace // IMPLEMENTATION -Program* Program::New( const Integration::ResourceId& resourceId, Integration::ShaderDataPtr shaderData, Context& context, bool modifiesGeometry ) +Program* Program::New( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry ) { size_t shaderHash = shaderData->GetHashValue(); - Program* program = context.GetCachedProgram( shaderHash ); + Program* program = cache.GetProgram( shaderHash ); if( NULL == program ) { // program not found so create it - program = new Program( shaderData, context, modifiesGeometry ); + program = new Program( cache, shaderData, modifiesGeometry ); - // we want to lazy load programs so dont do a Load yet, it gets done in Use - - // tell context to cache it - context.CacheProgram( shaderHash, program ); + // we want to lazy load programs so dont do a Load yet, it gets done in Use() + cache.AddProgram( shaderHash, program ); } return program; @@ -139,44 +120,72 @@ Program* Program::New( const Integration::ResourceId& resourceId, Integration::S void Program::Use() { - if ( !mLinked && - mContext.IsGlContextCreated() ) + if ( !mLinked ) { Load(); } if ( mLinked ) { - if ( this != mContext.GetCurrentProgram() ) + if ( this != mCache.GetCurrentProgram() ) { LOG_GL( "UseProgram(%d)\n", mProgramId ); - CHECK_GL( mContext, mGlAbstraction.UseProgram(mProgramId) ); - INCREASE_COUNTER(PerformanceMonitor::SHADER_STATE_CHANGES); + CHECK_GL( mGlAbstraction, mGlAbstraction.UseProgram(mProgramId) ); - mContext.SetCurrentProgram( this ); + mCache.SetCurrentProgram( this ); } } } bool Program::IsUsed() { - return ( this == mContext.GetCurrentProgram() ); + return ( this == mCache.GetCurrentProgram() ); } GLint Program::GetAttribLocation( AttribType type ) { DALI_ASSERT_DEBUG(type != ATTRIB_UNKNOWN); - if( mAttribLocations[ type ] == ATTRIB_UNKNOWN ) + return GetCustomAttributeLocation( type ); +} + +unsigned int Program::RegisterCustomAttribute( const std::string& name ) +{ + unsigned int index = 0; + // find the value from cache + for( ;index < mAttributeLocations.size(); ++index ) { - GLint loc = CHECK_GL( mContext, mGlAbstraction.GetAttribLocation( mProgramId, gStdAttribs[type] ) ); - mAttribLocations[ type ] = loc; - LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] ); + if( mAttributeLocations[ index ].first == name ) + { + // name found so return index + return index; + } } + // if we get here, index is one past end so push back the new name + mAttributeLocations.push_back( std::make_pair( name, ATTRIB_UNKNOWN ) ); + return index; +} + +GLint Program::GetCustomAttributeLocation( unsigned int attributeIndex ) +{ + // debug check that index is within name cache + DALI_ASSERT_DEBUG( mAttributeLocations.size() > attributeIndex ); + + // check if we have already queried the location of the attribute + GLint location = mAttributeLocations[ attributeIndex ].second; - return mAttribLocations[type]; + if( location == ATTRIB_UNKNOWN ) + { + location = CHECK_GL( mGlAbstraction, mGlAbstraction.GetAttribLocation( mProgramId, mAttributeLocations[ attributeIndex ].first.c_str() ) ); + + mAttributeLocations[ attributeIndex ].second = location; + LOG_GL( "GetAttributeLocation(program=%d,%s) = %d\n", mProgramId, mAttributeLocations[ attributeIndex ].first.c_str(), mAttributeLocations[ attributeIndex ].second ); + } + + return location; } + unsigned int Program::RegisterUniform( const std::string& name ) { unsigned int index = 0; @@ -204,7 +213,7 @@ GLint Program::GetUniformLocation( unsigned int uniformIndex ) if( location == UNIFORM_NOT_QUERIED ) { - location = CHECK_GL( mContext, mGlAbstraction.GetUniformLocation( mProgramId, mUniformLocations[ uniformIndex ].first.c_str() ) ); + location = CHECK_GL( mGlAbstraction, mGlAbstraction.GetUniformLocation( mProgramId, mUniformLocations[ uniformIndex ].first.c_str() ) ); mUniformLocations[ uniformIndex ].second = location; LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mUniformLocations[ uniformIndex ].first.c_str(), mUniformLocations[ uniformIndex ].second ); @@ -213,6 +222,91 @@ GLint Program::GetUniformLocation( unsigned int uniformIndex ) return location; } +namespace +{ +/** + * This struct is used to record the position of a uniform declaration + * within the fragment shader source code. + */ +struct LocationPosition +{ + GLint uniformLocation; ///< The location of the uniform (used as an identifier) + int characterPosition; ///< the position of the uniform declaration + LocationPosition( GLint uniformLocation, int characterPosition ) + : uniformLocation(uniformLocation), characterPosition(characterPosition) + { + } +}; + +bool sortByPosition( LocationPosition a, LocationPosition b ) +{ + return a.characterPosition < b.characterPosition; +} +} + +void Program::GetActiveSamplerUniforms() +{ + GLint numberOfActiveUniforms = -1; + GLint uniformMaxNameLength=-1; + + mGlAbstraction.GetProgramiv( mProgramId, GL_ACTIVE_UNIFORMS, &numberOfActiveUniforms ); + mGlAbstraction.GetProgramiv( mProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength ); + + std::vector samplerNames; + char name[uniformMaxNameLength+1]; // Allow for null terminator + std::vector< LocationPosition > samplerUniformLocations; + + { + int nameLength = -1; + int number = -1; + GLenum type = GL_ZERO; + + for( int i=0; i 1 ) + { + // Now, re-order according to declaration order in the fragment source. + std::string fragShader( mProgramData->GetFragmentShader() ); + for( unsigned int i=0; i= MAX_UNIFORM_CACHE_SIZE ) + { + // not cached, make the gl call + LOG_GL( "Uniform2f(%d,%f,%f)\n", location, value0, value1 ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform2f( location, value0, value1 ) ); + } + else + { + // check if the same value has already been set, reset if it is different + if( ( fabsf(value0 - mUniformCacheFloat2[ location ][ 0 ]) >= Math::MACHINE_EPSILON_1 )|| + ( fabsf(value1 - mUniformCacheFloat2[ location ][ 1 ]) >= Math::MACHINE_EPSILON_1 ) ) + { + // make the gl call + LOG_GL( "Uniform2f(%d,%f,%f)\n", location, value0, value1 ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform2f( location, value0, value1 ) ); + + // update cache + mUniformCacheFloat2[ location ][ 0 ] = value0; + mUniformCacheFloat2[ location ][ 1 ] = value1; + } + } +} + +void Program::SetSizeUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 ) +{ + if( ( fabsf(value0 - mSizeUniformCache.x) >= Math::MACHINE_EPSILON_1 )|| + ( fabsf(value1 - mSizeUniformCache.y) >= Math::MACHINE_EPSILON_1 )|| + ( fabsf(value2 - mSizeUniformCache.z) >= Math::MACHINE_EPSILON_1 ) ) + { + mSizeUniformCache.x = value0; + mSizeUniformCache.y = value1; + mSizeUniformCache.z = value2; + SetUniform3f( location, value0, value1, value2 ); + } } void Program::SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 ) @@ -328,7 +454,7 @@ void Program::SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfl // Not caching these as based on current analysis this is not called that often by our shaders LOG_GL( "Uniform3f(%d,%f,%f,%f)\n", location, value0, value1, value2 ); - CHECK_GL( mContext, mGlAbstraction.Uniform3f( location, value0, value1, value2 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform3f( location, value0, value1, value2 ) ); } void Program::SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3 ) @@ -348,7 +474,7 @@ void Program::SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfl { // not cached, make the gl call LOG_GL( "Uniform4f(%d,%f,%f,%f,%f)\n", location, value0, value1, value2, value3 ); - CHECK_GL( mContext, mGlAbstraction.Uniform4f( location, value0, value1, value2, value3 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform4f( location, value0, value1, value2, value3 ) ); } else { @@ -361,7 +487,7 @@ void Program::SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfl { // make the gl call LOG_GL( "Uniform4f(%d,%f,%f,%f,%f)\n", location, value0, value1, value2, value3 ); - CHECK_GL( mContext, mGlAbstraction.Uniform4f( location, value0, value1, value2, value3 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform4f( location, value0, value1, value2, value3 ) ); // update cache mUniformCacheFloat4[ location ][ 0 ] = value0; mUniformCacheFloat4[ location ][ 1 ] = value1; @@ -387,7 +513,7 @@ void Program::SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* // but with different values (we're using this for MVP matrices) // NOTE! we never want driver or GPU to transpose LOG_GL( "UniformMatrix4fv(%d,%d,GL_FALSE,%x)\n", location, count, value ); - CHECK_GL( mContext, mGlAbstraction.UniformMatrix4fv( location, count, GL_FALSE, value ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.UniformMatrix4fv( location, count, GL_FALSE, value ) ); } void Program::SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* value ) @@ -407,7 +533,7 @@ void Program::SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* // but with different values (we're using this for MVP matrices) // NOTE! we never want driver or GPU to transpose LOG_GL( "UniformMatrix3fv(%d,%d,GL_FALSE,%x)\n", location, count, value ); - CHECK_GL( mContext, mGlAbstraction.UniformMatrix3fv( location, count, GL_FALSE, value ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.UniformMatrix3fv( location, count, GL_FALSE, value ) ); } void Program::GlContextCreated() @@ -417,11 +543,9 @@ void Program::GlContextCreated() void Program::GlContextDestroyed() { mLinked = false; - mVertexShaderId = 0; mFragmentShaderId = 0; mProgramId = 0; - mContext.SetCurrentProgram( NULL ); ResetAttribsUniformCache(); } @@ -431,9 +555,9 @@ bool Program::ModifiesGeometry() return mModifiesGeometry; } -Program::Program(Integration::ShaderDataPtr shaderData, Context& context, bool modifiesGeometry ) -: mContext( context ), - mGlAbstraction( context.GetAbstraction() ), +Program::Program( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry ) +: mCache( cache ), + mGlAbstraction( mCache.GetGlAbstraction() ), mProjectionMatrix( NULL ), mViewMatrix( NULL ), mLinked( false ), @@ -443,6 +567,13 @@ Program::Program(Integration::ShaderDataPtr shaderData, Context& context, bool m mProgramData(shaderData), mModifiesGeometry( modifiesGeometry ) { + // reserve space for standard attributes + mAttributeLocations.reserve( ATTRIB_TYPE_LAST ); + for( int i=0; iHasBinary() ) + const bool binariesSupported = mCache.IsBinarySupported(); + + // if shader binaries are supported and ShaderData contains compiled bytecode? + if( binariesSupported && mProgramData->HasBinary() ) { - DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - Using Compiled Shader, Size = %d\n", mProgramData->buffer.size()); + DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - Using Compiled Shader, Size = %d\n", mProgramData->GetBufferSize()); - CHECK_GL( mContext, mGlAbstraction.ProgramBinary(mProgramId, mContext.CachedProgramBinaryFormat(), mProgramData->buffer.data(), mProgramData->buffer.size()) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.ProgramBinary(mProgramId, mCache.ProgramBinaryFormat(), mProgramData->GetBufferData(), mProgramData->GetBufferSize()) ); - CHECK_GL( mContext, mGlAbstraction.ValidateProgram(mProgramId) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.ValidateProgram(mProgramId) ); GLint success; - CHECK_GL( mContext, mGlAbstraction.GetProgramiv( mProgramId, GL_VALIDATE_STATUS, &success ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramiv( mProgramId, GL_VALIDATE_STATUS, &success ) ); DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "ValidateProgram Status = %d\n", success); - CHECK_GL( mContext, mGlAbstraction.GetProgramiv( mProgramId, GL_LINK_STATUS, &linked ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramiv( mProgramId, GL_LINK_STATUS, &linked ) ); if( GL_FALSE == linked ) { DALI_LOG_ERROR("Failed to load program binary \n"); - char* szLog = NULL; GLint nLength; - CHECK_GL( mContext, mGlAbstraction.GetProgramiv( mProgramId, GL_INFO_LOG_LENGTH, &nLength) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramiv( mProgramId, GL_INFO_LOG_LENGTH, &nLength) ); if(nLength > 0) { - szLog = new char[ nLength ]; - CHECK_GL( mContext, mGlAbstraction.GetProgramInfoLog( mProgramId, nLength, &nLength, szLog ) ); - DALI_LOG_ERROR( "Program Link Error: %s\n", szLog ); - - delete [] szLog; + Dali::Vector< char > szLog; + szLog.Reserve( nLength ); // Don't call Resize as we don't want to initialise the data, just reserve a buffer + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramInfoLog( mProgramId, nLength, &nLength, szLog.Begin() ) ); + DALI_LOG_ERROR( "Program Link Error: %s\n", szLog.Begin() ); } } else { mLinked = true; + DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "Reused binary.\n" ); } } @@ -512,49 +644,55 @@ void Program::Load() if( GL_FALSE == linked ) { DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - Runtime compilation\n"); - if( CompileShader( GL_VERTEX_SHADER, mVertexShaderId, mProgramData->vertexShader.c_str() ) ) + if( CompileShader( GL_VERTEX_SHADER, mVertexShaderId, mProgramData->GetVertexShader() ) ) { - if( CompileShader( GL_FRAGMENT_SHADER, mFragmentShaderId, mProgramData->fragmentShader.c_str() ) ) + if( CompileShader( GL_FRAGMENT_SHADER, mFragmentShaderId, mProgramData->GetFragmentShader() ) ) { Link(); - if( mLinked ) + if( binariesSupported && mLinked ) { GLint binaryLength = 0; GLenum binaryFormat; + DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "Compiled and linked.\n\nVS:\n%s\nFS:\n%s\n", mProgramData->GetVertexShader(), mProgramData->GetFragmentShader() ); - CHECK_GL( mContext, mGlAbstraction.GetProgramiv(mProgramId, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength) ); DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - GL_PROGRAM_BINARY_LENGTH_OES: %d\n", binaryLength); - - // Allocate space for the bytecode in ShaderData - mProgramData->AllocateBuffer(binaryLength); - // Copy the bytecode to ShaderData - CHECK_GL( mContext, mGlAbstraction.GetProgramBinary(mProgramId, binaryLength, NULL, &binaryFormat, mProgramData->buffer.data()) ); + if( binaryLength > 0 ) + { + // Allocate space for the bytecode in ShaderData + mProgramData->AllocateBuffer(binaryLength); + // Copy the bytecode to ShaderData + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramBinary(mProgramId, binaryLength, NULL, &binaryFormat, mProgramData->GetBufferData()) ); + mCache.StoreBinary( mProgramData ); + DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "Saved binary.\n" ); + } } } } } + GetActiveSamplerUniforms(); + // No longer needed FreeShaders(); - } void Program::Unload() { FreeShaders(); - if( this == mContext.GetCurrentProgram() ) + if( this == mCache.GetCurrentProgram() ) { - CHECK_GL( mContext, mGlAbstraction.UseProgram(0) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.UseProgram(0) ); - mContext.SetCurrentProgram( NULL ); + mCache.SetCurrentProgram( NULL ); } if (mProgramId) { LOG_GL( "DeleteProgram(%d)\n", mProgramId ); - CHECK_GL( mContext, mGlAbstraction.DeleteProgram( mProgramId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteProgram( mProgramId ) ); mProgramId = 0; } @@ -567,37 +705,37 @@ bool Program::CompileShader( GLenum shaderType, GLuint& shaderId, const char* sr if (!shaderId) { LOG_GL( "CreateShader(%d)\n", shaderType ); - shaderId = CHECK_GL( mContext, mGlAbstraction.CreateShader( shaderType ) ); + shaderId = CHECK_GL( mGlAbstraction, mGlAbstraction.CreateShader( shaderType ) ); LOG_GL( "AttachShader(%d,%d)\n", mProgramId, shaderId ); - CHECK_GL( mContext, mGlAbstraction.AttachShader( mProgramId, shaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.AttachShader( mProgramId, shaderId ) ); } LOG_GL( "ShaderSource(%d)\n", shaderId ); - CHECK_GL( mContext, mGlAbstraction.ShaderSource(shaderId, 1, &src, NULL ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.ShaderSource(shaderId, 1, &src, NULL ) ); LOG_GL( "CompileShader(%d)\n", shaderId ); - CHECK_GL( mContext, mGlAbstraction.CompileShader( shaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.CompileShader( shaderId ) ); GLint compiled; LOG_GL( "GetShaderiv(%d)\n", shaderId ); - CHECK_GL( mContext, mGlAbstraction.GetShaderiv( shaderId, GL_COMPILE_STATUS, &compiled ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetShaderiv( shaderId, GL_COMPILE_STATUS, &compiled ) ); if (compiled == GL_FALSE) { DALI_LOG_ERROR("Failed to compile shader\n"); LogWithLineNumbers(src); - std::vector< char > szLog; GLint nLength; mGlAbstraction.GetShaderiv( shaderId, GL_INFO_LOG_LENGTH, &nLength); if(nLength > 0) { - szLog.reserve( nLength ); - mGlAbstraction.GetShaderInfoLog( shaderId, nLength, &nLength, &szLog[ 0 ] ); - DALI_LOG_ERROR( "Shader Compiler Error: %s\n", &szLog[ 0 ] ); + Dali::Vector< char > szLog; + szLog.Reserve( nLength ); // Don't call Resize as we don't want to initialise the data, just reserve a buffer + mGlAbstraction.GetShaderInfoLog( shaderId, nLength, &nLength, szLog.Begin() ); + DALI_LOG_ERROR( "Shader Compiler Error: %s\n", szLog.Begin() ); } - throw DaliException( "Shader compilation failure", &szLog[ 0 ] ); + DALI_ASSERT_ALWAYS( 0 && "Shader compilation failure" ); } return compiled != 0; @@ -606,28 +744,27 @@ bool Program::CompileShader( GLenum shaderType, GLuint& shaderId, const char* sr void Program::Link() { LOG_GL( "LinkProgram(%d)\n", mProgramId ); - CHECK_GL( mContext, mGlAbstraction.LinkProgram( mProgramId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.LinkProgram( mProgramId ) ); GLint linked; LOG_GL( "GetProgramiv(%d)\n", mProgramId ); - CHECK_GL( mContext, mGlAbstraction.GetProgramiv( mProgramId, GL_LINK_STATUS, &linked ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.GetProgramiv( mProgramId, GL_LINK_STATUS, &linked ) ); if (linked == GL_FALSE) { DALI_LOG_ERROR("Shader failed to link \n"); - char* szLog = NULL; GLint nLength; mGlAbstraction.GetProgramiv( mProgramId, GL_INFO_LOG_LENGTH, &nLength); if(nLength > 0) { - szLog = new char[ nLength ]; - mGlAbstraction.GetProgramInfoLog( mProgramId, nLength, &nLength, szLog ); - DALI_LOG_ERROR( "Shader Link Error: %s\n", szLog ); - delete [] szLog; + Dali::Vector< char > szLog; + szLog.Reserve( nLength ); // Don't call Resize as we don't want to initialise the data, just reserve a buffer + mGlAbstraction.GetProgramInfoLog( mProgramId, nLength, &nLength, szLog.Begin() ); + DALI_LOG_ERROR( "Shader Link Error: %s\n", szLog.Begin() ); } - DALI_ASSERT_DEBUG(0); + DALI_ASSERT_ALWAYS( 0 && "Shader linking failure" ); } mLinked = linked != GL_FALSE; @@ -638,16 +775,16 @@ void Program::FreeShaders() if (mVertexShaderId) { LOG_GL( "DeleteShader(%d)\n", mVertexShaderId ); - CHECK_GL( mContext, mGlAbstraction.DetachShader( mProgramId, mVertexShaderId ) ); - CHECK_GL( mContext, mGlAbstraction.DeleteShader( mVertexShaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.DetachShader( mProgramId, mVertexShaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteShader( mVertexShaderId ) ); mVertexShaderId = 0; } if (mFragmentShaderId) { LOG_GL( "DeleteShader(%d)\n", mFragmentShaderId ); - CHECK_GL( mContext, mGlAbstraction.DetachShader( mProgramId, mFragmentShaderId ) ); - CHECK_GL( mContext, mGlAbstraction.DeleteShader( mFragmentShaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.DetachShader( mProgramId, mFragmentShaderId ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.DeleteShader( mFragmentShaderId ) ); mFragmentShaderId = 0; } } @@ -655,9 +792,9 @@ void Program::FreeShaders() void Program::ResetAttribsUniformCache() { // reset attribute locations - for( unsigned i = 0; i < ATTRIB_TYPE_LAST; ++i ) + for( unsigned i = 0; i < mAttributeLocations.size() ; ++i ) { - mAttribLocations[ i ] = ATTRIB_UNKNOWN; + mAttributeLocations[ i ].second = ATTRIB_UNKNOWN; } // reset all gl uniform locations @@ -667,12 +804,18 @@ void Program::ResetAttribsUniformCache() mUniformLocations[ i ].second = UNIFORM_NOT_QUERIED; } - // reset uniform cache + mSamplerUniformLocations.clear(); + + // reset uniform caches + mSizeUniformCache.x = mSizeUniformCache.y = mSizeUniformCache.z = 0.f; + for( int i = 0; i < MAX_UNIFORM_CACHE_SIZE; ++i ) { // GL initializes uniforms to 0 mUniformCacheInt[ i ] = 0; mUniformCacheFloat[ i ] = 0.0f; + mUniformCacheFloat2[ i ][ 0 ] = 0.0f; + mUniformCacheFloat2[ i ][ 1 ] = 0.0f; mUniformCacheFloat4[ i ][ 0 ] = 0.0f; mUniformCacheFloat4[ i ][ 1 ] = 0.0f; mUniformCacheFloat4[ i ][ 2 ] = 0.0f;