Cleaning up shader-effect-impl in preparation for future fixes 48/30048/4
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Fri, 7 Nov 2014 16:37:49 +0000 (16:37 +0000)
committerKimmo Hoikka <kimmo.hoikka@samsung.com>
Mon, 10 Nov 2014 12:43:41 +0000 (04:43 -0800)
[Problem]
[Cause]
[Solution]

Change-Id: Ieef7b50f71bf8462b6fc1c5b09d5473995eeb0bb

dali/internal/event/effects/shader-effect-impl.cpp
dali/internal/event/effects/shader-effect-impl.h
dali/internal/event/effects/shader-factory.cpp
dali/internal/event/effects/shader-factory.h
dali/public-api/shader-effects/shader-effect.cpp
dali/public-api/shader-effects/shader-effect.h

index cb802e4..e60c392 100644 (file)
@@ -19,7 +19,6 @@
 #include <dali/internal/event/effects/shader-effect-impl.h>
 
 // EXTERNAL INCLUDES
-#include <fstream>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/math/vector2.h>
@@ -93,6 +92,90 @@ WrapperStrings customShaderWrappers [] =
   }
 };
 
+/**
+ * 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( 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;
+
+    // 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;
+      }
+    }
+
+    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 );
+    }
+
+    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 );
+    }
+
+    effect.SendProgramMessage( expectedGeometryType, SHADER_SUBTYPE_ALL, vertexSource, fragmentSource, modifiesGeometry );
+  }
+}
+
 BaseHandle Create()
 {
   Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New();
@@ -119,80 +202,21 @@ const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
   Property::INTEGER,  // "geometry-hints",
 };
 
-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>() );
-}
-
 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();
+  return value;
 }
 
-} // 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;
-}
-
-ShaderEffectPtr ShaderEffect::New( const string& imageVertexShader,
-                                   const string& imageFragmentShader,
-                                   const string& textVertexShader,
-                                   const string& textFragmentShader,
-                                   const string& texturedMeshVertexShader,
-                                   const string& texturedMeshFragmentShader,
-                                   const string& untexturedMeshVertexShader,
-                                   const string& untexturedMeshFragmentShader,
-                                   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_UNTEXTURED_MESH, SHADER_SUBTYPE_ALL, "", "", untexturedMeshVertexShader, untexturedMeshFragmentShader );
-
-  return shaderEffect;
-}
+} // unnamed namespace
 
 ShaderEffectPtr ShaderEffect::New( Dali::ShaderEffect::GeometryHints hints )
 {
@@ -297,21 +321,49 @@ const Dali::ShaderEffect::Extension& ShaderEffect::GetExtension() const
   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 )
+{
+  SetPrograms( geometryType, "", "", vertexSource, fragmentSource );
+}
+
+void ShaderEffect::SetPrograms( GeometryType geometryType,
+                                const std::string& vertexPrefix, const std::string& fragmentPrefix,
+                                const std::string& vertexSource, const std::string& fragmentSource )
 {
-  SetProgramImpl(geometryType, subType, vertexSource, fragmentSource, 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::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::SendProgramMessage( GeometryType geometryType, ShaderSubTypes subType,
+                                       const string& vertexSource, const string& fragmentSource,
+                                       bool modifiesGeometry )
 {
-  const std::string vertex( vertexPrefix + vertexSource );
-  const std::string fragment( fragmentPrefix + fragmentSource );
-  SetProgramImpl( geometryType, subType, vertex, fragment, 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()
@@ -591,134 +643,6 @@ const PropertyInputImpl* ShaderEffect::GetSceneObjectInputProperty( Property::In
   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_UNTEXTURED_MESH )
-  {
-    SetWrappedProgram( GEOMETRY_TYPE_UNTEXTURED_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_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;
-    }
-  }
-
-  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.
-}
-
-
 } // namespace Internal
 
 } // namespace Dali
index f6ca2da..828e3c1 100644 (file)
@@ -60,67 +60,7 @@ public:
    * @param hints GeometryHints to define the geometry of the rendered object
    * @return A smart-pointer to a newly allocated shader effect.
    */
-  static ShaderEffectPtr New(Dali::ShaderEffect::GeometryHints hints = Dali::ShaderEffect::HINT_NONE);
-
-  /**
-   * Create a new ShaderEffect
-   * @param vertexShader code for the effect. If empty, the default version will be used
-   * @param fragmentShader code for the effect. If empty, the default version will be used
-   * @param type GeometryType
-   * @param hints GeometryHints to define the geometry of the rendered object
-   * @return A smart-pointer to a newly allocated shader effect.
-   */
-  static ShaderEffectPtr New( const std::string& vertexShader,
-                              const std::string& fragmentShader,
-                              GeometryType type,
-                              Dali::ShaderEffect::GeometryHints hints );
-  /**
-   * Create a new ShaderEffect
-   * @param vertexShaderPrefix code for the effect. It will be inserted before the default uniforms.
-   * @param vertexShader code for the effect. If empty, the default version will be used
-   * @param fragmentShaderPrefix code for the effect. It will be inserted before the default uniforms.
-   * @param fragmentShader code for the effect. If empty, the default version will be used
-   * @param type GeometryType
-   * @param hints GeometryHints to define the geometry of the rendered object
-   * @return A smart-pointer to a newly allocated shader effect.
-   */
-  static ShaderEffectPtr NewWithPrefix( const std::string& vertexShaderPrefix,
-                                        const std::string& vertexShader,
-                                        const std::string& fragmentShaderPrefix,
-                                        const std::string& fragmentShader,
-                                        GeometryType type,
-                                        Dali::ShaderEffect::GeometryHints hints );
-
-  /**
-   * Create a new ShaderEffect.
-   * If you pass in an empty string in the following arguments, the default version will be used instead.
-   * @param imageVertexShader code for the effect.
-   * @param imageFragmentShader code for the effect.
-   * @param textVertexShader code for the effect.
-   * @param textFragmentShader code for the effect.
-   * @param texturedMeshVertexShader code for the effect.
-   * @param texturedMeshFragmentShader code for the effect.
-   * @param meshVertexShader code for the effect.
-   * @param meshFragmentShader code for the effect.
-   * @param hints GeometryHints to define the geometry of the rendered object
-   * @return A handle to a shader effect
-   */
-  static ShaderEffectPtr New( const std::string& imageVertexShader,
-                              const std::string& imageFragmentShader,
-                              const std::string& textVertexShader,
-                              const std::string& textFragmentShader,
-                              const std::string& texturedMeshVertexShader,
-                              const std::string& texturedMeshFragmentShader,
-                              const std::string& meshVertexShader,
-                              const std::string& meshFragmentShader,
-                              Dali::ShaderEffect::GeometryHints hints );
-
-  /**
-   * Creates object with data from the property value map
-   * @param [in] map The property value map with fields such as 'vertex-filename' '..'
-   * @return a pointer to a newly created object.
-   */
-  static ShaderEffectPtr New( const Property::Value& map );
+  static ShaderEffectPtr New( Dali::ShaderEffect::GeometryHints hints = Dali::ShaderEffect::HINT_NONE );
 
   /**
    * @copydoc Dali::ShaderEffect::SetEffectImage
@@ -152,31 +92,36 @@ public:
   /**
    * Add a GeometryType specific default program to this ShaderEffect
    * @param[in] geometryType    The GeometryType rendered by the shader program
-   * @param[in] subType         The subtype, one of ShaderSubTypes.
    * @param[in] vertexSource    The source code for the vertex shader
    * @param[in] fragmentSource  The source code for the fragment shader
-   * @param[in] modifiesGeometry True if the shader modifies geometry
    */
-  void SetProgram( GeometryType geometryType, ShaderSubTypes subType,
-                   const std::string& vertexSource, const std::string& fragmentSource,
-                   GeometryState modifiesGeometry );
+  void SetPrograms( GeometryType geometryType, const std::string& vertexSource, const std::string& fragmentSource );
 
   /**
    * Add a GeometryType specific default program to this ShaderEffect.
    * This overload allows the optional prefixing for both the vertex and fragment shader.
    * A useful prefix may be shader \#defines for conditional compilation.
    * @param[in] geometryType    The GeometryType rendered by the shader program
-   * @param[in] subType         The subtype, one of ShaderSubTypes.
    * @param[in] vertexPrefix    The prefix source code for the vertex shader
    * @param[in] fragmentPrefix  The prefix source code for the fragment shader
    * @param[in] vertexSource    The source code for the vertex shader
    * @param[in] fragmentSource  The source code for the fragment shader
+   */
+  void SetPrograms( GeometryType geometryType,
+                    const std::string& vertexPrefix, const std::string& fragmentPrefix,
+                    const std::string& vertexSource, const std::string& fragmentSource );
+
+  /**
+   * Send shader program to scene-graph object.
+   * @param[in] geometryType     The GeometryType rendered by the shader program
+   * @param[in] subType          The subtype, one of ShaderSubTypes.
+   * @param[in] vertexSource     The source code for the vertex shader
+   * @param[in] fragmentSource   The source code for the fragment shader
    * @param[in] modifiesGeometry True if the shader modifies geometry
    */
-  void SetProgram( GeometryType geometryType, ShaderSubTypes subType,
-                   const std::string& vertexPrefix, const std::string& fragmentPrefix,
-                   const std::string& vertexSource, const std::string& fragmentSource,
-                   GeometryState modifiesGeometry );
+  void SendProgramMessage( GeometryType geometryType, ShaderSubTypes subType,
+                           const std::string& vertexSource, const std::string& fragmentSource,
+                           bool modifiesGeometry );
 
   /**
    * Notify ShaderEffect that it's being used by an Actor.
@@ -283,59 +228,6 @@ private:
   ShaderEffect( const ShaderEffect& );
   ShaderEffect& operator=( const ShaderEffect& rhs );
 
-  /**
-   * Set the given program for all shader types set in the geometryType bitfield.
-   * @param[in] geometryType         A GeometryType bitfield
-   * @param[in] vertexShaderPrefix   The prefix source code for the vertex shader
-   * @param[in] vertexShader         The source code for the vertex shader
-   * @param[in] fragmentShaderPrefix The prefix source code for the fragment shader
-   * @param[in] fragmentShader       The source code for the fragment shader
-   */
-  void SetPrograms( GeometryType  geometryTypes,
-                    const std::string& vertexShaderPrefix,
-                    const std::string& vertexShader,
-                    const std::string& fragmentShaderPrefix,
-                    const std::string& fragmentShader );
-
-  /**
-   * Wrap the given prefix and body code around the predefined prefix source for the
-   * given geometry type. Specifying an empty string for the body code means that the
-   * predefined body code is used instead.
-   *
-   * @param[in] geometryType    The GeometryType rendered by the shader program
-   * @param[in] subType         The subtype, one of ShaderSubTypes.
-   * @param[in] vertexPrefix    The prefix source code for the vertex shader
-   * @param[in] fragmentPrefix  The prefix source code for the fragment shader
-   * @param[in] vertexSource    The source code for the vertex shader
-   * @param[in] fragmentSource  The source code for the fragment shader
-   */
-  void SetWrappedProgram( GeometryType geometryType, ShaderSubTypes subType,
-                          const std::string& vertexPrefix, const std::string& fragmentPrefix,
-                          const std::string& vertexSource, const std::string& fragmentSource );
-
-  /**
-   * Send shader program to scene-graph object.
-   * Uses the shader hints to determine whether the shader modifies geometry
-   * @param[in] geometryType    The GeometryType rendered by the shader program
-   * @param[in] subType         The subtype, one of ShaderSubTypes.
-   * @param[in] vertexSource    The source code for the vertex shader
-   * @param[in] fragmentSource  The source code for the fragment shader
-   */
-  void SetProgramImpl( GeometryType geometryType, ShaderSubTypes subType,
-                       const std::string& vertexSource, const std::string& fragmentSource );
-
-  /**
-   * Send shader program to scene-graph object.
-   * @param[in] geometryType    The GeometryType rendered by the shader program
-   * @param[in] subType         The subtype, one of ShaderSubTypes.
-   * @param[in] vertexSource    The source code for the vertex shader
-   * @param[in] fragmentSource  The source code for the fragment shader
-   * @param[in] modifiesGeometry True if the shader modifies geometry
-   */
-  void SetProgramImpl( GeometryType geometryType, ShaderSubTypes subType,
-                       const std::string& vertexSource, const std::string& fragmentSource,
-                       GeometryState modifiesGeometry );
-
 private: // Data
 
   SceneGraph::UpdateManager& mUpdateManager;///< reference to the update manager
index aa2b98e..0dec5d4 100644 (file)
@@ -19,7 +19,6 @@
 #include <dali/internal/event/effects/shader-factory.h>
 
 // EXTERNAL INCLUDES
-#include <algorithm>
 #include <sstream>
 
 // INTERNAL INCLUDES
@@ -99,7 +98,7 @@ ResourceTicketPtr ShaderFactory::Load(const std::string& vertexSource, const std
 
   if ( !ticket )
   {
-    // Load a shader (loaded in Update thread)
+    // Load the shader (loaded synchronously in Update thread so its ready by the time the set shader message is processed)
     ticket = mResourceClient.LoadShader(resourceType, filename);
     DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "ShaderFactory::Load Ticket ID:%d, path: \"%s\"\n", ticket->GetId(), filename.c_str());
 
@@ -113,92 +112,74 @@ void ShaderFactory::LoadDefaultShaders()
 {
   mDefaultShader = ShaderEffect::New();
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_IMAGE, SHADER_DEFAULT, ImageVertex, ImageFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_IMAGE, SHADER_DEFAULT, ImageVertex, ImageFragment, false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_DEFAULT, TextDistanceFieldVertex, TextDistanceFieldFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_DEFAULT, TextDistanceFieldVertex, TextDistanceFieldFragment, false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT, SHADER_DEF_USE_GRADIENT, SHADER_DEF_USE_GRADIENT, TextDistanceFieldVertex, TextDistanceFieldFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT,
+                                      std::string( SHADER_DEF_USE_GRADIENT ) + TextDistanceFieldVertex,
+                                      std::string( SHADER_DEF_USE_GRADIENT ) + TextDistanceFieldFragment,
+                                      false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_GLOW, TextDistanceFieldGlowVertex, TextDistanceFieldGlowFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_GLOW, TextDistanceFieldGlowVertex, TextDistanceFieldGlowFragment, false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_SHADOW, TextDistanceFieldShadowVertex, TextDistanceFieldShadowFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_SHADOW, TextDistanceFieldShadowVertex, TextDistanceFieldShadowFragment, false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_OUTLINE, TextDistanceFieldOutlineVertex, TextDistanceFieldOutlineFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_OUTLINE, TextDistanceFieldOutlineVertex, TextDistanceFieldOutlineFragment, false );
 
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_OUTLINE_GLOW, TextDistanceFieldOutlineGlowVertex, TextDistanceFieldOutlineGlowFragment, ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXT, SHADER_GRADIENT_OUTLINE_GLOW, TextDistanceFieldOutlineGlowVertex, TextDistanceFieldOutlineGlowFragment, false );
 
   // Untextured meshes
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_DEFAULT,
-                              "", // Vertex shader defs
-                              SHADER_DEF_USE_LIGHTING, // fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::DOESNT_MODIFY_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_EVENLY_LIT,
-                              "", // Vertex shader defs
-                              "", // fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::DOESNT_MODIFY_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_LIT,
-                              SHADER_DEF_USE_BONES,    // vertex shader defs
-                              SHADER_DEF_USE_LIGHTING, // fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::MODIFIES_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_EVENLY_LIT,
-                              SHADER_DEF_USE_BONES, // Vertex shader defs
-                              "",                   // Fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::MODIFIES_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_VERTEX_COLOR,
-                              (SHADER_DEF_USE_BONES SHADER_DEF_USE_COLOR), // Vertex shader defs
-                              SHADER_DEF_USE_COLOR,                        // Fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::MODIFIES_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_VERTEX_COLOR,
-                              SHADER_DEF_USE_COLOR,  // Vertex shader defs
-                              SHADER_DEF_USE_COLOR,  // Fragment shader defs
-                              UntexturedMeshVertex,
-                              UntexturedMeshFragment,
-                              ShaderEffect::DOESNT_MODIFY_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_DEFAULT,
+                                      UntexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_LIGHTING ) + UntexturedMeshFragment,
+                                      false );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_EVENLY_LIT,
+                                      UntexturedMeshVertex,
+                                      UntexturedMeshFragment,
+                                      false );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_LIT,
+                                      std::string( SHADER_DEF_USE_BONES ) + UntexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_LIGHTING ) + UntexturedMeshFragment,
+                                      true );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_EVENLY_LIT,
+                                      std::string( SHADER_DEF_USE_BONES ) + UntexturedMeshVertex,
+                                      UntexturedMeshFragment,
+                                      true );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_RIGGED_AND_VERTEX_COLOR,
+                                      std::string( SHADER_DEF_USE_BONES SHADER_DEF_USE_COLOR ) + UntexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_COLOR ) + UntexturedMeshFragment,
+                                      true );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_UNTEXTURED_MESH, SHADER_VERTEX_COLOR,
+                                      std::string( SHADER_DEF_USE_COLOR ) + UntexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_COLOR ) + UntexturedMeshFragment,
+                                      false );
 
   // Textured meshes
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_DEFAULT,
-                              "",                      // Vertex shader defs
-                              SHADER_DEF_USE_LIGHTING, // fragment shader defs
-                              TexturedMeshVertex,
-                              TexturedMeshFragment,
-                              ShaderEffect::DOESNT_MODIFY_GEOMETRY );
-
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_EVENLY_LIT,
-                              "",                      // Vertex shader defs
-                              "",                      // Fragment shader defs
-                              TexturedMeshVertex,
-                              TexturedMeshFragment,
-                              ShaderEffect::DOESNT_MODIFY_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_RIGGED_AND_LIT,
-                              SHADER_DEF_USE_BONES,    // Vertex shader defs
-                              SHADER_DEF_USE_LIGHTING, // Fragment shader defs
-                              TexturedMeshVertex,
-                              TexturedMeshFragment,
-                              ShaderEffect::MODIFIES_GEOMETRY );
-
-  mDefaultShader->SetProgram( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_RIGGED_AND_EVENLY_LIT,
-                              SHADER_DEF_USE_BONES, // Vertex shader defs
-                              "",                   // Fragment shader defs
-                              TexturedMeshVertex,
-                              TexturedMeshFragment,
-                              ShaderEffect::MODIFIES_GEOMETRY );
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_DEFAULT,
+                                      TexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_LIGHTING ) + TexturedMeshFragment,
+                                      false );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_EVENLY_LIT,
+                                      TexturedMeshVertex,
+                                      TexturedMeshFragment,
+                                      false );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_RIGGED_AND_LIT,
+                                      std::string( SHADER_DEF_USE_BONES ) + TexturedMeshVertex,
+                                      std::string( SHADER_DEF_USE_LIGHTING ) + TexturedMeshFragment,
+                                      true );
+
+  mDefaultShader->SendProgramMessage( GEOMETRY_TYPE_TEXTURED_MESH, SHADER_RIGGED_AND_EVENLY_LIT,
+                                      std::string( SHADER_DEF_USE_BONES ) + TexturedMeshVertex,
+                                      TexturedMeshFragment,
+                                      true );
 }
 
 } // namespace Internal
index 861d394..fd5a07f 100644 (file)
@@ -43,14 +43,14 @@ class ShaderFactory
 public:
 
   /**
-   * default constructor
+   * Default constructor
    */
   ShaderFactory(ResourceClient& resourceClient);
 
   /**
-   * Default destructor
+   * Destructor
    */
-  virtual ~ShaderFactory();
+  ~ShaderFactory();
 
   /**
    * Issues a request to load a binary version of a shader program, and returns a resource ticket
index eafbf20..6f440e1 100644 (file)
@@ -62,7 +62,9 @@ ShaderEffect& ShaderEffect::operator=(const ShaderEffect& rhs)
 
 ShaderEffect ShaderEffect::New( const std::string& vertexShader, const std::string& fragmentShader, GeometryType type, GeometryHints hints)
 {
-  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( vertexShader, fragmentShader, type, hints );
+  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( hints );
+
+  internal->SetPrograms( type, vertexShader, fragmentShader );
 
   return ShaderEffect( internal.Get() );
 }
@@ -74,7 +76,9 @@ ShaderEffect ShaderEffect::NewWithPrefix( const std::string& vertexShaderPrefix,
                                           GeometryType type,
                                           GeometryHints hints)
 {
-  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::NewWithPrefix( vertexShaderPrefix, vertexShader, fragmentShaderPrefix, fragmentShader, type, hints );
+  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( hints );
+
+  internal->SetPrograms( type, vertexShaderPrefix, fragmentShaderPrefix, vertexShader, fragmentShader );
 
   return ShaderEffect( internal.Get() );
 }
@@ -85,7 +89,10 @@ ShaderEffect ShaderEffect::New( const std::string& imageVertexShader,
                                 const std::string& textFragmentShader,
                                 GeometryHints hints)
 {
-  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( imageVertexShader, imageFragmentShader, textVertexShader, textFragmentShader, "", "", "", "", hints );
+  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( hints );
+
+  internal->SetPrograms( GEOMETRY_TYPE_IMAGE, imageVertexShader, imageFragmentShader );
+  internal->SetPrograms( GEOMETRY_TYPE_TEXT, textVertexShader, textFragmentShader );
 
   return ShaderEffect( internal.Get() );
 }
@@ -100,7 +107,12 @@ ShaderEffect ShaderEffect::New( const std::string& imageVertexShader,
                                 const std::string& meshFragmentShader,
                                 GeometryHints hints)
 {
-  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( imageVertexShader, imageFragmentShader, textVertexShader, textFragmentShader, texturedMeshVertexShader, texturedMeshFragmentShader, meshVertexShader, meshFragmentShader, hints );
+  Internal::ShaderEffectPtr internal = Internal::ShaderEffect::New( hints );
+
+  internal->SetPrograms( GEOMETRY_TYPE_IMAGE, imageVertexShader, imageFragmentShader );
+  internal->SetPrograms( GEOMETRY_TYPE_TEXT, textVertexShader, textFragmentShader );
+  internal->SetPrograms( GEOMETRY_TYPE_TEXTURED_MESH, texturedMeshVertexShader, texturedMeshFragmentShader );
+  internal->SetPrograms( GEOMETRY_TYPE_UNTEXTURED_MESH, meshVertexShader, meshFragmentShader );
 
   return ShaderEffect( internal.Get() );
 }
index a9fe2c8..1f404a8 100644 (file)
@@ -185,8 +185,8 @@ public:
    */
   static const Property::Index GRID_DENSITY;       ///< name "grid-density",   type FLOAT
   static const Property::Index IMAGE;              ///< name "image",          type MAP; {"filename":"", "load-policy":...}
-  static const Property::Index PROGRAM;            ///< name "program",        type MAP; {"vertex-filename":"",...}
-  static const Property::Index GEOMETRY_HINTS;     ///< name "geometry-hints", type INT (bitfield)
+  static const Property::Index PROGRAM;            ///< name "program",        type MAP; {"vertex-prefix":"","fragment-prefix":"","vertex":"","fragment":""}
+  static const Property::Index GEOMETRY_HINTS;     ///< name "geometry-hints", type INT (bitfield) values from enum GeometryHints
 
   static const float DEFAULT_GRID_DENSITY;         ///< The default density is 40 pixels