X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Fshaders%2Fprogram.cpp;h=530b6292a8d4dac82d4a362256724736cb25779d;hb=4d75040ab200bd306ec5a48f2a617480062eef4c;hp=a2367f6fd817d2c777dddeb831a0e9fea0cefd11;hpb=9ef925cf1da2d99130aae7026c88055611666950;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp old mode 100644 new mode 100755 index a2367f6..530b629 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include @@ -110,8 +111,7 @@ Program* Program::New( ProgramCache& cache, Internal::ShaderDataPtr shaderData, { // program not found so create it program = new Program( cache, shaderData, modifiesGeometry ); - - // we want to lazy load programs so dont do a Load yet, it gets done in Use() + program->Load(); cache.AddProgram( shaderHash, program ); } @@ -120,11 +120,6 @@ Program* Program::New( ProgramCache& cache, Internal::ShaderDataPtr shaderData, void Program::Use() { - if ( !mLinked ) - { - Load(); - } - if ( mLinked ) { if ( this != mCache.GetCurrentProgram() ) @@ -222,29 +217,123 @@ GLint Program::GetUniformLocation( unsigned int uniformIndex ) return location; } -GLint Program::GetSamplerUniformLocation( int32_t uniqueIndex, const std::string& samplerName ) +namespace +{ +/** + * This struct is used to record the position of a uniform declaration + * within the fragment shader source code. + */ +struct LocationPosition { - // don't accept negative values (should never happen) - DALI_ASSERT_DEBUG( 0 <= uniqueIndex ); - const uint32_t index( uniqueIndex ); // avoid compiler warning of signed vs unsigned comparisons + GLint uniformLocation; ///< The location of the uniform (used as an identifier) + int position; ///< the position of the uniform declaration + LocationPosition( GLint uniformLocation, int position ) + : uniformLocation(uniformLocation), position(position) + { + } +}; - GLint location = UNIFORM_NOT_QUERIED; +bool sortByPosition( LocationPosition a, LocationPosition b ) +{ + return a.position < b.position; +} +} + +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; + std::vector name(uniformMaxNameLength + 1); // Allow for null terminator + std::vector< LocationPosition > samplerUniformLocations; - if( index < mSamplerUniformLocations.Size() ) { - location = mSamplerUniformLocations[ index ]; + int nameLength = -1; + int number = -1; + GLenum type = GL_ZERO; + + for( int i=0; i( i ), uniformMaxNameLength, + &nameLength, &number, &type, name.data() ); + + if( type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES ) + { + GLuint location = mGlAbstraction.GetUniformLocation( mProgramId, name.data() ); + samplerNames.push_back( name.data() ); + samplerUniformLocations.push_back(LocationPosition(location, -1)); + } + } } - else + + //Determine declaration order of each sampler + char* fragShader = strdup( mProgramData->GetFragmentShader() ); + char* nextPtr = NULL; + const char* token = strtok_r( fragShader, " ;\n", &nextPtr ); + int samplerPosition = 0; + while( token ) + { + if( ( strncmp( token, "sampler2D", 9u ) == 0 ) || + ( strncmp( token, "samplerCube", 11u ) == 0 ) || + ( strncmp( token, "samplerExternalOES", 18u ) == 0 ) ) + { + bool found( false ); + token = strtok_r( NULL, " ;\n", &nextPtr ); + for( size_t i=0; i 1 ) { - // not in cache yet, make space and initialize value to not queried - mSamplerUniformLocations.Resize( index + 1, UNIFORM_NOT_QUERIED ); + std::sort( samplerUniformLocations.begin(), samplerUniformLocations.end(), sortByPosition); } - if( location == UNIFORM_NOT_QUERIED ) + + mSamplerUniformLocations.resize( samplerUniformCount ); + for( size_t i=0; i