X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Fshaders%2Fprogram.cpp;h=ec464892bbcf3bdcfa11feb9402f6997aa855a45;hb=6a9a86815730fc72cdb815b9f577e50f4f3cb49d;hp=061c06e1713c104b034dc0fded8c8d1c57d8b2d1;hpb=18a19a784dc40ae5376de548921fa29698eccc25;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp index 061c06e..ec46489 100644 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -1,32 +1,36 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ // CLASS HEADER #include // EXTERNAL INCLUDES -#include #include // INTERNAL INCLUDES #include +#include #include -#include #include #include +#include +#include +#include +#include namespace { @@ -117,20 +121,19 @@ const char* gStdUniforms[ Program::UNIFORM_TYPE_LAST ] = // IMPLEMENTATION -Program* Program::New( const Integration::ResourceId& resourceId, Integration::ShaderData* shaderData, Context& context ) +Program* Program::New( ProgramCache& cache, Integration::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 ); + program = new Program( cache, shaderData, modifiesGeometry ); - program->Load(); + // 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 ); + cache.AddProgram( shaderHash, program ); } return program; @@ -138,28 +141,27 @@ 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) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.UseProgram(mProgramId) ); INCREASE_COUNTER(PerformanceMonitor::SHADER_STATE_CHANGES); - mContext.SetCurrentProgram( this ); + mCache.SetCurrentProgram( this ); } } } bool Program::IsUsed() { - return ( this == mContext.GetCurrentProgram() ); + return ( this == mCache.GetCurrentProgram() ); } GLint Program::GetAttribLocation( AttribType type ) @@ -168,9 +170,9 @@ GLint Program::GetAttribLocation( AttribType type ) if( mAttribLocations[ type ] == ATTRIB_UNKNOWN ) { - LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] ); - GLint loc = CHECK_GL( mContext, mGlAbstraction.GetAttribLocation( mProgramId, gStdAttribs[type] ) ); + GLint loc = CHECK_GL( mGlAbstraction, mGlAbstraction.GetAttribLocation( mProgramId, gStdAttribs[type] ) ); mAttribLocations[ type ] = loc; + LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] ); } return mAttribLocations[type]; @@ -203,10 +205,10 @@ GLint Program::GetUniformLocation( unsigned int uniformIndex ) if( location == UNIFORM_NOT_QUERIED ) { - 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() ) ); + 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 ); } return location; @@ -227,18 +229,18 @@ void Program::SetUniform1i( GLint location, GLint value0 ) // check if uniform location fits the cache if( location >= MAX_UNIFORM_CACHE_SIZE ) { - // not cached, make the gl call through context + // not cached, make the gl call LOG_GL( "Uniform1i(%d,%d)\n", location, value0 ); - CHECK_GL( mContext, mGlAbstraction.Uniform1i( location, value0 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform1i( location, value0 ) ); } else { // check if the value is different from what's already been set if( value0 != mUniformCacheInt[ location ] ) { - // make the gl call through context + // make the gl call LOG_GL( "Uniform1i(%d,%d)\n", location, value0 ); - CHECK_GL( mContext, mGlAbstraction.Uniform1i( location, value0 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform1i( location, value0 ) ); // update cache mUniformCacheInt[ location ] = value0; } @@ -259,7 +261,7 @@ void Program::SetUniform4i( GLint location, GLint value0, GLint value1, GLint va // Not caching these as based on current analysis this is not called that often by our shaders LOG_GL( "Uniform4i(%d,%d,%d,%d,%d)\n", location, value0, value1, value2, value3 ); - CHECK_GL( mContext, mGlAbstraction.Uniform4i( location, value0, value1, value2, value3 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform4i( location, value0, value1, value2, value3 ) ); } void Program::SetUniform1f( GLint location, GLfloat value0 ) @@ -277,18 +279,18 @@ void Program::SetUniform1f( GLint location, GLfloat value0 ) // check if uniform location fits the cache if( location >= MAX_UNIFORM_CACHE_SIZE ) { - // not cached, make the gl call through context + // not cached, make the gl call LOG_GL( "Uniform1f(%d,%f)\n", location, value0 ); - CHECK_GL( mContext, mGlAbstraction.Uniform1f( location, value0 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform1f( location, value0 ) ); } else { // check if the same value has already been set, reset if it is different if( ( fabsf(value0 - mUniformCacheFloat[ location ]) >= Math::MACHINE_EPSILON_1 ) ) { - // make the gl call through context + // make the gl call LOG_GL( "Uniform1f(%d,%f)\n", location, value0 ); - CHECK_GL( mContext, mGlAbstraction.Uniform1f( location, value0 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform1f( location, value0 ) ); // update cache mUniformCacheFloat[ location ] = value0; @@ -310,7 +312,7 @@ void Program::SetUniform2f( GLint location, GLfloat value0, GLfloat value1 ) // Not caching these as based on current analysis this is not called that often by our shaders LOG_GL( "Uniform2f(%d,%f,%f)\n", location, value0, value1 ); - CHECK_GL( mContext, mGlAbstraction.Uniform2f( location, value0, value1 ) ); + CHECK_GL( mGlAbstraction, mGlAbstraction.Uniform2f( location, value0, value1 ) ); } void Program::SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 ) @@ -327,7 +329,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 ) @@ -345,9 +347,9 @@ void Program::SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfl // check if uniform location fits the cache if( location >= MAX_UNIFORM_CACHE_SIZE ) { - // not cached, make the gl call through context + // 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 { @@ -358,9 +360,9 @@ void Program::SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfl ( fabsf(value1 - mUniformCacheFloat4[ location ][ 1 ]) >= Math::MACHINE_EPSILON_1 )|| ( fabsf(value2 - mUniformCacheFloat4[ location ][ 2 ]) >= Math::MACHINE_EPSILON_1 ) ) { - // make the gl call through context + // 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; @@ -382,12 +384,11 @@ void Program::SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* return; } - // Not caching these calls. Based on current analysis this is called very often // but with different values (we're using this for MVP matrices) - // NOTE! we never want GPU to transpose + // 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 ) @@ -405,39 +406,41 @@ void Program::SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* // Not caching these calls. Based on current analysis this is called very often // but with different values (we're using this for MVP matrices) - // NOTE! we never want GPU to transpose + // 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() { - if (!mLinked) - { - Load(); - } } -void Program::GlContextToBeDestroyed() +void Program::GlContextDestroyed() { - Unload(); - + mLinked = false; mVertexShaderId = 0; mFragmentShaderId = 0; mProgramId = 0; - mContext.SetCurrentProgram( NULL ); - ResetAttribsUniforms(); + ResetAttribsUniformCache(); } -Program::Program(Integration::ShaderData* shaderData, Context& context ) -: mContext( context ), - mGlAbstraction( context.GetAbstraction() ), +bool Program::ModifiesGeometry() +{ + return mModifiesGeometry; +} + +Program::Program( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bool modifiesGeometry ) +: mCache( cache ), + mGlAbstraction( mCache.GetGlAbstraction() ), + mProjectionMatrix( NULL ), + mViewMatrix( NULL ), mLinked( false ), mVertexShaderId( 0 ), mFragmentShaderId( 0 ), mProgramId( 0 ), - mProgramData(shaderData) + mProgramData(shaderData), + mModifiesGeometry( modifiesGeometry ) { // reserve space for standard uniforms mUniformLocations.reserve( UNIFORM_TYPE_LAST ); @@ -447,59 +450,53 @@ Program::Program(Integration::ShaderData* shaderData, Context& context ) RegisterUniform( gStdUniforms[ i ] ); } // reset values - ResetAttribsUniforms(); - - mContext.AddObserver( *this ); + ResetAttribsUniformCache(); } Program::~Program() { - mContext.RemoveObserver( *this ); - - Unload(); // Resets gCurrentProgram + Unload(); } void Program::Load() { - DALI_ASSERT_ALWAYS( NULL != mProgramData && "Program data is not initialized" ); - - Unload(); + DALI_ASSERT_ALWAYS( NULL != mProgramData.Get() && "Program data is not initialized" ); LOG_GL( "CreateProgram()\n" ); - mProgramId = CHECK_GL( mContext, mGlAbstraction.CreateProgram() ); + mProgramId = CHECK_GL( mGlAbstraction, mGlAbstraction.CreateProgram() ); GLint linked = GL_FALSE; - // ShaderData contains compiled bytecode? - if( 0 != mContext.CachedNumberOfProgramBinaryFormats() && mProgramData->HasBinary() ) + 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 @@ -512,24 +509,27 @@ 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; - 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 ); + } } } } @@ -537,24 +537,23 @@ void Program::Load() // 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 +566,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 +605,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,21 +636,21 @@ 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; } } -void Program::ResetAttribsUniforms() +void Program::ResetAttribsUniformCache() { // reset attribute locations for( unsigned i = 0; i < ATTRIB_TYPE_LAST; ++i )