// CLASS HEADER
#include <dali/internal/event/effects/shader-effect-impl.h>
-// EXTERNAL INCLUDES
-#include <fstream>
-
// INTERNAL INCLUDES
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/matrix.h>
#include <dali/public-api/shader-effects/shader-effect.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/scripting/scripting.h>
-#include "dali-shaders.h"
#include <dali/internal/event/effects/shader-declarations.h>
#include <dali/internal/event/effects/shader-factory.h>
#include <dali/internal/event/images/image-impl.h>
#include <dali/internal/event/common/stage-impl.h>
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/render/shaders/shader.h>
-#include <dali/internal/update/common/property-owner-messages.h>
+#include <dali/internal/render/shaders/uniform-meta.h>
#include <dali/internal/update/animation/scene-graph-constraint-base.h>
+#include "dali-shaders.h"
using Dali::Internal::SceneGraph::UpdateManager;
using Dali::Internal::SceneGraph::UniformMeta;
using Dali::Internal::SceneGraph::Shader;
using Dali::Internal::SceneGraph::AnimatableProperty;
using Dali::Internal::SceneGraph::PropertyBase;
-using Dali::Internal::SceneGraph::PropertyBase;
using Dali::Internal::SceneGraph::RenderQueue;
using std::string;
namespace Internal
{
-ShaderEffect::DefaultPropertyLookup* ShaderEffect::mDefaultPropertyLookup = NULL;
-
namespace
{
+const PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
+{
+ // Name Type writable animatable constraint-input
+ { "grid-density", Property::FLOAT, true, false, false }, // GRID_DENSITY
+ { "image", Property::MAP, true, false, false }, // IMAGE
+ { "program", Property::MAP, true, false, false }, // PROGRAM
+ { "geometry-hints", Property::INTEGER, true, false, false }, // GEOMETRY_HINTS
+};
+
+const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( DEFAULT_PROPERTY_DETAILS[0] );
+
+BaseHandle Create()
+{
+ Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New();
+
+ return Dali::ShaderEffect(internal.Get());
+}
+
+TypeRegistration mType( typeid(Dali::ShaderEffect), typeid(Dali::Handle), Create );
struct WrapperStrings
{
CustomImagePostfixVertex, CustomImagePostfixFragment
},
{
- CustomFontPrefixVertex, CustomFontPrefixFragment,
- CustomFontPostfixVertex, CustomFontPostfixFragment
+ CustomTextDistanceFieldPrefixVertex, CustomTextDistanceFieldPrefixFragment,
+ CustomTextDistanceFieldPostfixVertex, CustomTextDistanceFieldPostfixFragment
+ },
+ {
+ CustomUntexturedMeshPrefixVertex, CustomUntexturedMeshPrefixFragment,
+ CustomUntexturedMeshPostfixVertex, CustomUntexturedMeshPostfixFragment
},
{
- CustomMeshPrefixVertex, CustomMeshPrefixFragment,
- CustomMeshPostfixVertex, CustomMeshPostfixFragment
+ CustomTexturedMeshPrefixVertex, CustomTexturedMeshPrefixFragment,
+ CustomTexturedMeshPostfixVertex, CustomTexturedMeshPostfixFragment
}
};
-BaseHandle Create()
-{
- Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New();
-
- return Dali::ShaderEffect(internal.Get());
-}
+/**
+ * Helper to wrap the program with our default pre and postfix if needed and then send it to update/render thread
+ * @param[in] effect of the shader
+ * @param[in] actualGeometryType of the shader
+ * @param[in] expectedGeometryType of the shader
+ * @param[in] vertexPrefix from application
+ * @param[in] fragmentPrefix from application
+ * @param[in] vertexBody from application
+ * @param[in] fragmentBody from application
+ * @param[in] modifiesGeometry based on flags and vertex shader
+ */
+void WrapAndSetProgram( Internal::ShaderEffect& effect,
+ GeometryType actualGeometryType, GeometryType expectedGeometryType,
+ const std::string& vertexPrefix, const std::string& fragmentPrefix,
+ const std::string& vertexBody, const std::string& fragmentBody,
+ bool modifiesGeometry )
+{
+ // if geometry type matches and there is some real data in the strings
+ if( ( actualGeometryType & expectedGeometryType )&&
+ ( ( vertexPrefix.length() > 0 )||
+ ( fragmentPrefix.length() > 0 )||
+ ( vertexBody.length() > 0 )||
+ ( fragmentBody.length() > 0 ) ) )
+ {
+ std::string vertexSource = vertexPrefix;
+ std::string fragmentSource = fragmentPrefix;
-TypeRegistration mType( typeid(Dali::ShaderEffect), typeid(Dali::Handle), Create );
+ // create complete shader program strings for the given geometry type
+ unsigned int index = 0;
+ switch( expectedGeometryType )
+ {
+ case GEOMETRY_TYPE_IMAGE:
+ {
+ index = 0;
+ break;
+ }
+ case GEOMETRY_TYPE_TEXT:
+ {
+ index = 1;
+ break;
+ }
+ case GEOMETRY_TYPE_UNTEXTURED_MESH:
+ {
+ index = 2;
+ break;
+ }
+ case GEOMETRY_TYPE_TEXTURED_MESH:
+ {
+ index = 3;
+ break;
+ }
+ case GEOMETRY_TYPE_LAST:
+ {
+ DALI_ASSERT_DEBUG(0 && "Wrong geometry type");
+ break;
+ }
+ }
-const std::string DEFAULT_PROPERTY_NAMES[] =
-{
- "grid-density",
- "image",
- "program",
- "geometry-hints",
-};
-const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
+ vertexSource += customShaderWrappers[index].vertexShaderPrefix;
+ // Append the custom vertex shader code if supplied, otherwise append the default
+ if ( vertexBody.length() > 0 )
+ {
+ vertexSource.append( vertexBody );
+ }
+ else
+ {
+ vertexSource.append( customShaderWrappers[index].vertexShaderPostfix );
+ }
-const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
-{
- Property::FLOAT, // "grid-density",
- Property::MAP, // "image",
- Property::MAP, // "program",
- Property::INTEGER, // "geometry-hints",
-};
+ fragmentSource += customShaderWrappers[index].fragmentShaderPrefix;
+ // Append the custom fragment shader code if supplied, otherwise append the default
+ if ( fragmentBody.length() > 0 )
+ {
+ fragmentSource.append( fragmentBody );
+ }
+ else
+ {
+ fragmentSource.append( customShaderWrappers[index].fragmentShaderPostfix );
+ }
-std::string GetFileContents( const std::string& filename )
-{
- std::ifstream input( filename.c_str() );
- return std::string( std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>() );
+ effect.SendProgramMessage( expectedGeometryType, SHADER_SUBTYPE_ALL, vertexSource, fragmentSource, modifiesGeometry );
+ }
}
std::string GetShader(const std::string& field, const Property::Value& property)
{
+ std::string value;
if( property.HasKey(field) )
{
DALI_ASSERT_ALWAYS(property.GetValue(field).GetType() == Property::STRING && "Shader property is not a string" );
// we could also check here for an array of strings as convenience for json not having multi line strings
- return property.GetValue(field).Get<std::string>();
- }
- else
- {
- // convention of shader field appended with -filename signifies a file
- std::string filenameKey(std::string(field) + std::string("-filename"));
-
- if( property.HasKey( filenameKey ) )
- {
- DALI_ASSERT_ALWAYS(property.GetValue(filenameKey).GetType() == Property::STRING && "Shader filename property is not a string" );
- // this should eventually be done by an adaptor interface
- return GetFileContents( property.GetValue(filenameKey).Get<std::string>() );
- }
+ value = property.GetValue(field).Get<std::string>();
}
- return std::string();
-}
-
-} // anon namespace
-
-
-ShaderEffectPtr ShaderEffect::New( const string& vertexShader,
- const string& fragmentShader,
- GeometryType geometryType,
- Dali::ShaderEffect::GeometryHints hints )
-{
- return NewWithPrefix( "", vertexShader, "", fragmentShader, geometryType, hints);
-}
-
-ShaderEffectPtr ShaderEffect::NewWithPrefix( const string& vertexShaderPrefix,
- const string& vertexShader,
- const string& fragmentShaderPrefix,
- const string& fragmentShader,
- GeometryType geometryTypes,
- Dali::ShaderEffect::GeometryHints hints )
-{
- ShaderEffectPtr shaderEffect( New(hints) );
-
- shaderEffect->SetPrograms( geometryTypes, vertexShaderPrefix, vertexShader, fragmentShaderPrefix, fragmentShader );
- return shaderEffect;
+ return value;
}
-ShaderEffectPtr ShaderEffect::New( const string& imageVertexShader,
- const string& imageFragmentShader,
- const string& textVertexShader,
- const string& textFragmentShader,
- const string& texturedMeshVertexShader,
- const string& texturedMeshFragmentShader,
- const string& meshVertexShader,
- const string& meshFragmentShader,
- Dali::ShaderEffect::GeometryHints hints )
-{
- ShaderEffectPtr shaderEffect( New(hints) );
-
- shaderEffect->SetWrappedProgram( GEOMETRY_TYPE_IMAGE, SHADER_SUBTYPE_ALL, "", "", imageVertexShader, imageFragmentShader );
- shaderEffect->SetWrappedProgram( GEOMETRY_TYPE_TEXT, SHADER_DEFAULT, "", "", textVertexShader, textFragmentShader );
- shaderEffect->SetWrappedProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_SUBTYPE_ALL, "", "", texturedMeshVertexShader, texturedMeshFragmentShader );
- shaderEffect->SetWrappedProgram( GEOMETRY_TYPE_MESH, SHADER_SUBTYPE_ALL, "", "", meshVertexShader, meshFragmentShader );
-
- return shaderEffect;
-}
+} // unnamed namespace
ShaderEffectPtr ShaderEffect::New( Dali::ShaderEffect::GeometryHints hints )
{
ShaderEffect::~ShaderEffect()
{
- DALI_ASSERT_DEBUG( mSceneObject != NULL );
-
// Guard to allow handle destruction after Core has been destroyed
if ( Stage::IsInstalled() )
{
// Remove scene-object using a message to the UpdateManager
- RemoveShaderMessage( mUpdateManager, *mSceneObject );
-
+ if( mSceneObject )
+ {
+ RemoveShaderMessage( mUpdateManager, *mSceneObject );
+ }
UnregisterObject();
}
}
SetProperty( index, value );
- SetCoordinateTypeMessage( mUpdateManager.GetEventToUpdate(), *mCustomMetadata[index], uniformCoordinateType );
+ // RegisterProperty guarantees a positive value as index
+ DALI_ASSERT_DEBUG( static_cast<unsigned int>(index) >= CustomPropertyStartIndex() );
+ unsigned int metaIndex = index - CustomPropertyStartIndex();
+ // check if there's space in cache
+ if( mCoordinateTypes.Count() < (metaIndex + 1) )
+ {
+ mCoordinateTypes.Resize( metaIndex + 1 );
+ }
+ // only send message if the value is different than current, initial value is COORDINATE_TYPE_DEFAULT (0)
+ if( uniformCoordinateType != mCoordinateTypes[ metaIndex ] )
+ {
+ mCoordinateTypes[ metaIndex ] = uniformCoordinateType;
+ SetCoordinateTypeMessage( mUpdateManager.GetEventToUpdate(), *mSceneObject, metaIndex, uniformCoordinateType );
+ }
}
void ShaderEffect::AttachExtension( Dali::ShaderEffect::Extension *extension )
return *mExtension;
}
-void ShaderEffect::SetProgram( GeometryType geometryType, ShaderSubTypes subType,
- const string& vertexSource, const string& fragmentSource,
- GeometryState modifiesGeometry )
+void ShaderEffect::SetPrograms( GeometryType geometryType, const string& vertexSource, const string& fragmentSource )
{
- SetProgramImpl(geometryType, subType, vertexSource, fragmentSource, modifiesGeometry);
+ SetPrograms( geometryType, "", "", vertexSource, fragmentSource );
}
-void ShaderEffect::SetProgram( GeometryType geometryType, ShaderSubTypes subType,
- const std::string& vertexPrefix, const std::string& fragmentPrefix,
- const std::string& vertexSource, const std::string& fragmentSource,
- GeometryState modifiesGeometry )
+void ShaderEffect::SetPrograms( GeometryType geometryType,
+ const std::string& vertexPrefix, const std::string& fragmentPrefix,
+ const std::string& vertexSource, const std::string& fragmentSource )
{
- const std::string vertex( vertexPrefix + vertexSource );
- const std::string fragment( fragmentPrefix + fragmentSource );
- SetProgramImpl( geometryType, subType, vertex, fragment, modifiesGeometry );
+ bool modifiesGeometry = true;
+ // check if the vertex shader is empty (means it cannot modify geometry)
+ if( (vertexPrefix.length() == 0 )&&( vertexSource.length() == 0 ) )
+ {
+ modifiesGeometry = false;
+ }
+ // check the hint second
+ if( (mGeometryHints & Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY ) != 0 )
+ {
+ modifiesGeometry = false;
+ }
+
+ WrapAndSetProgram( *this, geometryType, GEOMETRY_TYPE_IMAGE, vertexPrefix, fragmentPrefix, vertexSource, fragmentSource, modifiesGeometry );
+ WrapAndSetProgram( *this, geometryType, GEOMETRY_TYPE_TEXT, vertexPrefix, fragmentPrefix, vertexSource, fragmentSource, modifiesGeometry );
+ WrapAndSetProgram( *this, geometryType, GEOMETRY_TYPE_TEXTURED_MESH, vertexPrefix, fragmentPrefix, vertexSource, fragmentSource, modifiesGeometry );
+ WrapAndSetProgram( *this, geometryType, GEOMETRY_TYPE_UNTEXTURED_MESH, vertexPrefix, fragmentPrefix, vertexSource, fragmentSource, modifiesGeometry );
+}
+
+void ShaderEffect::SendProgramMessage( GeometryType geometryType, ShaderSubTypes subType,
+ const string& vertexSource, const string& fragmentSource,
+ bool modifiesGeometry )
+{
+ ThreadLocalStorage& tls = ThreadLocalStorage::Get();
+ ShaderFactory& shaderFactory = tls.GetShaderFactory();
+ size_t shaderHash;
+
+ ResourceTicketPtr ticket( shaderFactory.Load(vertexSource, fragmentSource, shaderHash) );
+
+ DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "ShaderEffect: SetProgram(geometryType %d subType:%d ticket.id:%d)\n", geometryType, subType, ticket->GetId() );
+
+ // Add shader program to scene-object using a message to the UpdateManager
+ SetShaderProgramMessage( mUpdateManager, *mSceneObject, geometryType, subType, ticket->GetId(), shaderHash, modifiesGeometry );
+
+ mTickets.push_back(ticket); // add ticket to collection to keep it alive.
}
void ShaderEffect::Connect()
}
}
-bool ShaderEffect::IsSceneObjectRemovable() const
-{
- return false; // The Shader is not removed during this proxy's lifetime
-}
-
unsigned int ShaderEffect::GetDefaultPropertyCount() const
{
return DEFAULT_PROPERTY_COUNT;
}
}
-const std::string& ShaderEffect::GetDefaultPropertyName(Property::Index index) const
+const char* ShaderEffect::GetDefaultPropertyName(Property::Index index) const
{
if( index < DEFAULT_PROPERTY_COUNT )
{
- return DEFAULT_PROPERTY_NAMES[index];
+ return DEFAULT_PROPERTY_DETAILS[index].name;
}
else
{
- // index out of range..return empty string
- static const std::string INVALID_PROPERTY_NAME;
- return INVALID_PROPERTY_NAME;
+ return NULL;
}
}
{
Property::Index index = Property::INVALID_INDEX;
- // Lazy initialization of static mDefaultPropertyLookup
- if (!mDefaultPropertyLookup)
+ // Look for name in default properties
+ for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
{
- mDefaultPropertyLookup = new DefaultPropertyLookup();
-
- for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
+ const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
+ if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
{
- (*mDefaultPropertyLookup)[DEFAULT_PROPERTY_NAMES[i]] = i;
+ index = i;
+ break;
}
}
- DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
-
- // Look for name in default properties
- DefaultPropertyLookup::const_iterator result = mDefaultPropertyLookup->find( name );
- if ( mDefaultPropertyLookup->end() != result )
- {
- index = result->second;
- }
return index;
+
}
bool ShaderEffect::IsDefaultPropertyWritable(Property::Index index) const
{
- return true;
+ return true; // all properties are writable
}
bool ShaderEffect::IsDefaultPropertyAnimatable(Property::Index index) const
{
- return false;
+ return false; // all properties are non animatable
}
bool ShaderEffect::IsDefaultPropertyAConstraintInput( Property::Index index ) const
{
- return false;
+ return false; // all properties cannot be used as constraint input
}
Property::Type ShaderEffect::GetDefaultPropertyType(Property::Index index) const
{
if( index < DEFAULT_PROPERTY_COUNT )
{
- return DEFAULT_PROPERTY_TYPES[index];
+ return DEFAULT_PROPERTY_DETAILS[index].type;
}
else
{
{
geometryType = GEOMETRY_TYPE_TEXT;
}
- else if( s == "GEOMETRY_TYPE_MESH")
+ else if( s == "GEOMETRY_TYPE_UNTEXTURED_MESH")
{
- geometryType = GEOMETRY_TYPE_MESH;
+ geometryType = GEOMETRY_TYPE_UNTEXTURED_MESH;
}
else if( s == "GEOMETRY_TYPE_TEXTURED_MESH")
{
DALI_ASSERT_ALWAYS(!"Geometry type unknown" );
}
}
- SetPrograms( geometryType, vertexPrefix, vertex, fragmentPrefix, fragment );
+ SetPrograms( geometryType, vertexPrefix, fragmentPrefix, vertex, fragment );
break;
}
default:
{
- DALI_ASSERT_ALWAYS(false && "ShaderEffect property enumeration out of range"); // should not come here
+ // nothing to do
break;
}
}
return Property::Value();
}
-void ShaderEffect::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
+void ShaderEffect::NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
{
// Warning - the property is added to the Shader object in the Update thread and the meta-data is added in the Render thread (through a secondary message)
- // mSceneObject is being used in a separate thread; queue a message to add the property
- InstallCustomPropertyMessage( mUpdateManager.GetEventToUpdate(), *mSceneObject, newProperty ); // Message takes ownership
-
// mSceneObject requires metadata for each custom property (uniform)
UniformMeta* meta = UniformMeta::New( name, newProperty, Dali::ShaderEffect::COORDINATE_TYPE_DEFAULT );
// mSceneObject is being used in a separate thread; queue a message to add the property
InstallUniformMetaMessage( mUpdateManager.GetEventToUpdate(), *mSceneObject, *meta ); // Message takes ownership
-
- // Add entry to the metadata lookup
- mCustomMetadata[index] = meta;
}
const SceneGraph::PropertyOwner* ShaderEffect::GetSceneObject() const
const PropertyBase* ShaderEffect::GetSceneObjectAnimatableProperty( Property::Index index ) const
{
- CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
-
- DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "Property index is invalid" );
-
- DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "shader effect has only animatable properties" );
-
- return dynamic_cast<const PropertyBase*>( entry->second.GetSceneGraphProperty() );
+ CustomProperty* custom = FindCustomProperty( index );
+ DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
+ return custom->GetSceneGraphProperty();
}
const PropertyInputImpl* ShaderEffect::GetSceneObjectInputProperty( Property::Index index ) const
{
- CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
-
- DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "Property index is invalid" );
-
- DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "shader effect has only animatable properties" );
-
- return entry->second.GetSceneGraphProperty();
-}
-
-void ShaderEffect::SetPrograms( GeometryType geometryTypes,
- const std::string& vertexShaderPrefix,
- const std::string& vertexShader,
- const std::string& fragmentShaderPrefix,
- const std::string& fragmentShader )
-{
- static std::string emptyStr;
-
- if( geometryTypes & GEOMETRY_TYPE_IMAGE )
- {
- SetWrappedProgram( GEOMETRY_TYPE_IMAGE, SHADER_SUBTYPE_ALL, vertexShaderPrefix, fragmentShaderPrefix, vertexShader, fragmentShader );
- }
-
- if( geometryTypes & GEOMETRY_TYPE_TEXT )
- {
- // Only change the default program, leaving the other sub-types as-is.
- SetWrappedProgram( GEOMETRY_TYPE_TEXT, SHADER_DEFAULT, vertexShaderPrefix, fragmentShaderPrefix, vertexShader, fragmentShader );
- }
-
- if( geometryTypes & GEOMETRY_TYPE_TEXTURED_MESH )
- {
- SetWrappedProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_SUBTYPE_ALL, vertexShaderPrefix, fragmentShaderPrefix, vertexShader, fragmentShader );
- }
-
- if( geometryTypes & GEOMETRY_TYPE_MESH )
- {
- SetWrappedProgram( GEOMETRY_TYPE_MESH, SHADER_SUBTYPE_ALL, vertexShaderPrefix, fragmentShaderPrefix, vertexShader, fragmentShader );
- }
-}
-
-void ShaderEffect::SetWrappedProgram( GeometryType geometryType, ShaderSubTypes subType,
- const string& vertexPrefix, const string& fragmentPrefix,
- const string& vertexSnippet, const string& fragmentSnippet )
-{
- // create complete shader program strings for the given geometry type
- unsigned int index = 0;
- switch( geometryType )
- {
- case GEOMETRY_TYPE_IMAGE:
- {
- index = 0;
- break;
- }
- case GEOMETRY_TYPE_TEXT:
- {
- index = 1;
- break;
- }
- case GEOMETRY_TYPE_MESH:
- case GEOMETRY_TYPE_TEXTURED_MESH:
- {
- index = 2;
- break;
- }
- case GEOMETRY_TYPE_LAST:
- {
- DALI_ASSERT_DEBUG(0 && "Wrong geometry type");
- break;
- }
- }
-
- string vertexSource = vertexPrefix + customShaderWrappers[index].vertexShaderPrefix;
- string fragmentSource = fragmentPrefix + customShaderWrappers[index].fragmentShaderPrefix;
-
- // Append the custom vertex shader code if supplied, otherwise append the default
- if ( vertexSnippet.length() > 0 )
- {
- vertexSource.append( vertexSnippet );
- }
- else
- {
- vertexSource.append( customShaderWrappers[index].vertexShaderPostfix );
- }
-
- // Append the custom fragment shader code if supplied, otherwise append the default
- if ( fragmentSnippet.length() > 0 )
- {
- fragmentSource.append( fragmentSnippet );
- }
- else
- {
- fragmentSource.append( customShaderWrappers[index].fragmentShaderPostfix );
- }
-
- // Add the program
- SetProgramImpl( geometryType, subType, vertexSource, fragmentSource );
-}
-
-void ShaderEffect::SetProgramImpl( GeometryType geometryType, ShaderSubTypes subType,
- const string& vertexSource, const string& fragmentSource )
-{
- GeometryState modifiesGeometry = MODIFIES_GEOMETRY;
-
- if( (mGeometryHints & Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY ) != 0 )
- {
- modifiesGeometry = DOESNT_MODIFY_GEOMETRY;
- }
-
- SetProgramImpl( geometryType, subType, vertexSource, fragmentSource, modifiesGeometry );
-}
-
-void ShaderEffect::SetProgramImpl( GeometryType geometryType, ShaderSubTypes subType,
- const string& vertexSource, const string& fragmentSource,
- GeometryState modifiesGeometry )
-{
- // Load done asynchronously in update thread. SetProgram message below must be processed afterwards.
- // Therefore, resource manager cannot farm out the loading to the adaptor resource threads,
- // but must instead use synchronous loading via PlatformAbstraction::LoadFile()
-
- ThreadLocalStorage& tls = ThreadLocalStorage::Get();
- ShaderFactory& shaderFactory = tls.GetShaderFactory();
- size_t shaderHash;
-
- ResourceTicketPtr ticket( shaderFactory.Load(vertexSource, fragmentSource, shaderHash) );
-
- DALI_LOG_INFO( Debug::Filter::gShader, Debug::General, "ShaderEffect: SetProgram(geometryType %d subType:%d ticket.id:%d)\n", geometryType, subType, ticket->GetId() );
-
- // Add shader program to scene-object using a message to the UpdateManager
- SetShaderProgramMessage( mUpdateManager, *mSceneObject, geometryType, subType, ticket->GetId(), shaderHash, modifiesGeometry==MODIFIES_GEOMETRY );
-
- mTickets.push_back(ticket); // add ticket to collection to keep it alive.
+ return GetSceneObjectAnimatableProperty( index );
}
-
} // namespace Internal
} // namespace Dali