removal of shader inheritance, renderable actors now have shaders and there is a... 15/25415/8
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Mon, 4 Aug 2014 16:46:10 +0000 (17:46 +0100)
committerPaul Wisbey <p.wisbey@samsung.com>
Wed, 13 Aug 2014 10:17:42 +0000 (03:17 -0700)
requires https://review.tizen.org/gerrit/#/c/25510/

[Problem]
[Cause]
[Solution]

Change-Id: I09f525cfe6ba34068ab6c1ae8bd247744eb7d272

27 files changed:
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Handle.cpp
automated-tests/src/dali/utc-Dali-RenderableActor.cpp
dali/internal/common/message.h
dali/internal/event/actor-attachments/renderable-attachment-impl.cpp
dali/internal/event/actor-attachments/renderable-attachment-impl.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/renderable-actor-impl.cpp
dali/internal/event/actors/renderable-actor-impl.h
dali/internal/update/controllers/scene-controller-impl.cpp
dali/internal/update/controllers/scene-controller-impl.h
dali/internal/update/controllers/scene-controller.h
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/manager/update-algorithms.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/node-attachments/scene-graph-image-attachment.cpp
dali/internal/update/node-attachments/scene-graph-mesh-attachment.cpp
dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp
dali/internal/update/node-attachments/scene-graph-renderable-attachment.h
dali/internal/update/node-attachments/scene-graph-text-attachment.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/actors/actor.cpp
dali/public-api/actors/actor.h
dali/public-api/actors/renderable-actor.cpp
dali/public-api/actors/renderable-actor.h

index 2a3342d..d810d07 100644 (file)
@@ -40,19 +40,6 @@ void utc_dali_actor_cleanup(void)
 namespace
 {
 
-const char* vertexSource =
-"void main()\n"
-"{\n"
-"  gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n"
-"  vTexCoord = aTexCoord;\n"
-"}\n";
-
-const char* fragmentSource =
-"void main()\n"
-"{\n"
-"  gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n"
-"}\n";
-
 bool gTouchCallBackCalled=false;
 bool gTouchCallBack2Called=false;
 
@@ -1548,94 +1535,6 @@ int UtcDaliActorIsSensitive(void)
   END_TEST;
 }
 
-int UtcDaliActorSetInheritShaderEffect(void)
-{
-  TestApplication application;
-
-  Actor actor = Actor::New();
-
-  actor.SetInheritShaderEffect(false);
-  // flush the queue and render once
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_CHECK(actor.GetInheritShaderEffect() == false);
-
-  actor.SetInheritShaderEffect(true);
-  // flush the queue and render once
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_CHECK(actor.GetInheritShaderEffect() == true);
-  END_TEST;
-}
-
-int UtcDaliActorGetInheritShaderEffect(void)
-{
-  TestApplication application;
-
-  Actor actor = Actor::New();
-
-  DALI_TEST_CHECK(actor.GetInheritShaderEffect() == true);
-  END_TEST;
-}
-
-int UtcDaliActorSetShaderEffect(void)
-{
-  TestApplication application;
-  Actor actor = Actor::New();
-
-  ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
-
-  DALI_TEST_CHECK(effect != actor.GetShaderEffect());
-
-  actor.SetShaderEffect(effect);
-
-  DALI_TEST_CHECK(effect == actor.GetShaderEffect());
-  END_TEST;
-}
-
-int UtcDaliActorGetShaderEffect(void)
-{
-  TestApplication application;
-  Actor actor = Actor::New();
-
-  ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
-  actor.SetShaderEffect(effect);
-
-  DALI_TEST_CHECK(effect == actor.GetShaderEffect());
-  END_TEST;
-}
-
-int UtcDaliActorRemoveShaderEffect01(void)
-{
-  TestApplication application;
-  Actor actor = Actor::New();
-
-  ShaderEffect defaultEffect = actor.GetShaderEffect();
-
-  ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
-  actor.SetShaderEffect(effect);
-
-  DALI_TEST_CHECK(effect == actor.GetShaderEffect());
-
-  actor.RemoveShaderEffect();
-
-  DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
-  END_TEST;
-}
-
-int UtcDaliActorRemoveShaderEffect02(void)
-{
-  TestApplication application;
-  Actor actor = Actor::New();
-
-  ShaderEffect defaultEffect = actor.GetShaderEffect();
-
-  actor.RemoveShaderEffect();
-
-  DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
-  END_TEST;
-}
-
 int UtcDaliActorSetColor(void)
 {
   TestApplication application;
@@ -2984,7 +2883,6 @@ const PropertyStringIndex PROPERTY_TABLE[] =
   { "name",                     Actor::NAME,                    Property::STRING      },
   { "sensitive",                Actor::SENSITIVE,               Property::BOOLEAN     },
   { "leave-required",           Actor::LEAVE_REQUIRED,          Property::BOOLEAN     },
-  { "inherit-shader-effect",    Actor::INHERIT_SHADER_EFFECT,   Property::BOOLEAN     },
   { "inherit-rotation",         Actor::INHERIT_ROTATION,        Property::BOOLEAN     },
   { "inherit-scale",            Actor::INHERIT_SCALE,           Property::BOOLEAN     },
   { "color-mode",               Actor::COLOR_MODE,              Property::STRING      },
index 8ff666b..1747227 100644 (file)
@@ -405,7 +405,6 @@ int UtcDaliHandleIsPropertyAConstraintInput(void)
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::NAME ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::SENSITIVE ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::LEAVE_REQUIRED ) );
-  DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_SHADER_EFFECT ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_ROTATION ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_SCALE ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::COLOR_MODE ) );
index 5eaea36..dfea428 100644 (file)
@@ -734,3 +734,170 @@ int UtcDaliRenderableActorSetFilterMode(void)
 
   END_TEST;
 }
+
+int UtcDaliRenderableActorSetShaderEffect(void)
+{
+  TestApplication application;
+  BitmapImage img = BitmapImage::New( 1,1 );
+  ImageActor actor = ImageActor::New( img );
+  Stage::GetCurrent().Add( actor );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+  GLuint lastShaderCompiledBefore = application.GetGlAbstraction().GetLastShaderCompiled();
+
+  application.GetGlAbstraction().EnableShaderCallTrace( true );
+
+  const std::string vertexShader = "UtcDaliRenderableActorSetShaderEffect-VertexSource";
+  const std::string fragmentShader = "UtcDaliRenderableActorSetShaderEffect-FragmentSource";
+  ShaderEffect effect = ShaderEffect::New(vertexShader, fragmentShader );
+  DALI_TEST_CHECK( effect != actor.GetShaderEffect() );
+
+  actor.SetShaderEffect( effect );
+  DALI_TEST_CHECK( effect == actor.GetShaderEffect() );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  GLuint lastShaderCompiledAfter = application.GetGlAbstraction().GetLastShaderCompiled();
+  DALI_TEST_EQUALS( lastShaderCompiledAfter, lastShaderCompiledBefore + 2, TEST_LOCATION );
+
+  std::string actualVertexShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 1 );
+  DALI_TEST_EQUALS( vertexShader,
+                    actualVertexShader.substr( actualVertexShader.length() - vertexShader.length() ), TEST_LOCATION );
+  std::string actualFragmentShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 2 );
+  DALI_TEST_EQUALS( fragmentShader,
+                    actualFragmentShader.substr( actualFragmentShader.length() - fragmentShader.length() ), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRenderableActorGetShaderEffect(void)
+{
+  TestApplication application;
+  TextActor actor = TextActor::New();
+
+  ShaderEffect effect = ShaderEffect::New("UtcDaliRenderableActorGetShaderEffect-VertexSource", "UtcDaliRenderableActorGetShaderEffect-FragmentSource" );
+  actor.SetShaderEffect(effect);
+
+  DALI_TEST_CHECK(effect == actor.GetShaderEffect());
+  END_TEST;
+}
+
+int UtcDaliRenderableActorRemoveShaderEffect01(void)
+{
+  TestApplication application;
+  TextActor actor = TextActor::New();
+
+  ShaderEffect defaultEffect = actor.GetShaderEffect();
+
+  ShaderEffect effect = ShaderEffect::New("UtcDaliRenderableActorRemoveShaderEffect-VertexSource", "UtcDaliRenderableActorRemoveShaderEffect-FragmentSource" );
+  actor.SetShaderEffect(effect);
+
+  DALI_TEST_CHECK(effect == actor.GetShaderEffect());
+
+  actor.RemoveShaderEffect();
+
+  DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
+  END_TEST;
+}
+
+int UtcDaliRenderableActorRemoveShaderEffect02(void)
+{
+  TestApplication application;
+  TextActor actor = TextActor::New();
+
+  ShaderEffect defaultEffect = actor.GetShaderEffect();
+
+  actor.RemoveShaderEffect();
+
+  DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
+  END_TEST;
+}
+
+int UtcDaliSetShaderEffectRecursively(void)
+{
+  TestApplication application;
+  /**
+   * create a tree
+   *                 actor1
+   *           actor2       actor4
+   *       actor3 textactor
+   * imageactor
+   */
+  BitmapImage img = BitmapImage::New( 1,1 );
+  ImageActor actor1 = ImageActor::New( img );
+  Actor actor2 = Actor::New();
+  actor1.Add( actor2 );
+  Actor actor3 = Actor::New();
+  actor2.Add( actor3 );
+  TextActor textactor = TextActor::New( "Foo" );
+  actor2.Add( textactor );
+  ImageActor imageactor = ImageActor::New( img );
+  actor3.Add( imageactor );
+  Actor actor4 = Actor::New();
+  actor1.Add( actor4 );
+  Stage::GetCurrent().Add( actor1 );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+  GLuint lastShaderCompiledBefore = application.GetGlAbstraction().GetLastShaderCompiled();
+
+  application.GetGlAbstraction().EnableShaderCallTrace( true );
+
+  const std::string vertexShader = "UtcDaliRenderableActorSetShaderEffect-VertexSource";
+  const std::string fragmentShader = "UtcDaliRenderableActorSetShaderEffect-FragmentSource";
+  // test with empty effect
+  ShaderEffect effect;
+  SetShaderEffectRecursively( actor1, effect );
+
+  effect = ShaderEffect::New(vertexShader, fragmentShader );
+
+  DALI_TEST_CHECK( effect != actor1.GetShaderEffect() );
+  DALI_TEST_CHECK( effect != textactor.GetShaderEffect() );
+  DALI_TEST_CHECK( effect != imageactor.GetShaderEffect() );
+
+  SetShaderEffectRecursively( actor1, effect );
+  DALI_TEST_CHECK( effect == textactor.GetShaderEffect() );
+  DALI_TEST_CHECK( effect == imageactor.GetShaderEffect() );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  GLuint lastShaderCompiledAfter = application.GetGlAbstraction().GetLastShaderCompiled();
+  DALI_TEST_EQUALS( lastShaderCompiledAfter, lastShaderCompiledBefore + 2, TEST_LOCATION );
+
+  std::string actualVertexShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 1 );
+  DALI_TEST_EQUALS( vertexShader,
+                    actualVertexShader.substr( actualVertexShader.length() - vertexShader.length() ), TEST_LOCATION );
+  std::string actualFragmentShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 2 );
+  DALI_TEST_EQUALS( fragmentShader,
+                    actualFragmentShader.substr( actualFragmentShader.length() - fragmentShader.length() ), TEST_LOCATION );
+
+  // remove from one that does not have shader
+  RemoveShaderEffectRecursively( actor4 );
+
+  // remove partially
+  RemoveShaderEffectRecursively( actor3 );
+  DALI_TEST_CHECK( effect == textactor.GetShaderEffect() );
+  DALI_TEST_CHECK( effect != imageactor.GetShaderEffect() );
+
+  // test with empty actor just to check it does not crash
+  Actor empty;
+  SetShaderEffectRecursively( empty, effect );
+  RemoveShaderEffectRecursively( empty );
+
+  // test with actor with no children just to check it does not crash
+  Actor loner = Actor::New();
+  Stage::GetCurrent().Add( loner );
+  SetShaderEffectRecursively( loner, effect );
+  DALI_TEST_CHECK( effect != loner.GetShaderEffect() ); // base actor does not have shader effects
+  RemoveShaderEffectRecursively( loner );
+
+  END_TEST;
+}
+
index 13c67bb..201186c 100644 (file)
@@ -545,6 +545,55 @@ private:
 
 /**
  * Templated message which calls a member function of an object.
+ * This overload passes just the buffer index to the method, no parameters.
+ */
+template< typename T >
+class MessageDoubleBuffered0 : public MessageBase
+{
+public:
+
+  typedef void(T::*MemberFunction)( BufferIndex );
+
+  /**
+   * Create a message.
+   * @note The object is expected to be const in the thread which sends this message.
+   * However it can be modified when Process() is called in a different thread.
+   * @param[in] obj The object.
+   * @param[in] member The member function of the object.
+   */
+  MessageDoubleBuffered0( const T* obj, MemberFunction member )
+  : MessageBase(),
+    object( const_cast< T* >( obj ) ),
+    memberFunction( member )
+  {
+  }
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~MessageDoubleBuffered0()
+  {
+  }
+
+  /**
+   * @copydoc MessageBase::Process
+   */
+  virtual void Process( BufferIndex bufferIndex )
+  {
+    DALI_ASSERT_DEBUG( object && "Message does not have an object" );
+    (object->*memberFunction)( bufferIndex );
+  }
+
+private:
+
+  T* object;
+  MemberFunction memberFunction;
+
+};
+
+
+/**
+ * Templated message which calls a member function of an object.
  * This overload passes a value-type to set a double-buffered property.
  * Template parameters need to match the MemberFunction!
  * The message will contain copy of the value (in case of & or const&)
index 84d4d71..80a2a27 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
 #include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
-#include <dali/internal/render/renderers/scene-graph-renderer.h>
+
+using Dali::Internal::SceneGraph::Shader;
 
 namespace Dali
 {
@@ -31,10 +33,12 @@ namespace Internal
 
 RenderableAttachment::RenderableAttachment( Stage& stage )
 : ActorAttachment( stage ),
+  mShaderEffect(),
+  mBlendingOptions(),
+  mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ),
   mSortModifier( 0.0f ),
   mCullFaceMode( CullNone ),
-  mBlendingMode( BlendingMode::AUTO ),
-  mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) )
+  mBlendingMode( BlendingMode::AUTO )
 {
 }
 
@@ -153,15 +157,75 @@ void RenderableAttachment::GetFilterMode( FilterMode::Type& minFilter, FilterMod
   magFilter = ImageSampler::GetMagnifyFilterMode( mSamplerBitfield );
 }
 
+void RenderableAttachment::SetShaderEffect(ShaderEffect& effect)
+{
+  if ( OnStage() )
+  {
+    if ( mShaderEffect )
+    {
+      mShaderEffect->Disconnect();
+    }
+
+    mShaderEffect.Reset( &effect );
+
+    const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
+
+    ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
+
+    mShaderEffect->Connect();
+  }
+  else
+  {
+    mShaderEffect = ShaderEffectPtr(&effect);
+  }
+  // Effects can only be applied when the Node is connected to scene-graph
+}
+
+ShaderEffectPtr RenderableAttachment::GetShaderEffect() const
+{
+  return mShaderEffect;
+}
+
+void RenderableAttachment::RemoveShaderEffect()
+{
+  if ( OnStage() )
+  {
+    RemoveShaderMessage( mStage->GetUpdateInterface(), GetSceneObject() );
+
+    // Notify shader effect
+    if (mShaderEffect)
+    {
+      mShaderEffect->Disconnect();
+    }
+  }
+
+  mShaderEffect.Reset();
+}
 
 void RenderableAttachment::OnStageConnection()
 {
+  if ( mShaderEffect )
+  {
+    const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
+
+    ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
+
+    // Notify shader effect
+    mShaderEffect->Connect();
+  }
+
   // For derived classes
   OnStageConnection2();
 }
 
 void RenderableAttachment::OnStageDisconnection()
 {
+  // Notify shader effect
+  if ( mShaderEffect )
+  {
+    mShaderEffect->Disconnect();
+  }
+
   // For derived classes
   OnStageDisconnection2();
 }
index 5900e71..4c48c8a 100644 (file)
@@ -35,6 +35,8 @@ namespace SceneGraph
 {
 class RenderableAttachment;
 }
+class ShaderEffect;
+typedef IntrusivePtr<ShaderEffect> ShaderEffectPtr;
 
 /**
  * An base class for renderable actor attachments
@@ -121,6 +123,21 @@ public:
    */
   void GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter ) const;
 
+  /**
+   * @copydoc Dali::RenderableActor::SetShaderEffect
+   */
+  void SetShaderEffect(ShaderEffect& effect);
+
+  /**
+   * @copydoc Dali::RenderableActor::GetShaderEffect
+   */
+  ShaderEffectPtr GetShaderEffect() const;
+
+  /**
+   * @copydoc Dali::RenderableActor::RemoveShaderEffect
+   */
+  void RemoveShaderEffect();
+
 protected:
 
   /**
@@ -174,14 +191,16 @@ private:
    */
   virtual const SceneGraph::RenderableAttachment& GetSceneObject() const = 0;
 
-private:
+private: // Data, cached for actor-thread getters
 
-  // Cached for actor-thread getters
-  float              mSortModifier;
-  CullFaceMode       mCullFaceMode;
-  BlendingMode::Type mBlendingMode;
+  ShaderEffectPtr    mShaderEffect;    ///< Optional referenced shader effect
   BlendingOptions    mBlendingOptions;
   unsigned int       mSamplerBitfield;
+  float              mSortModifier;
+  CullFaceMode       mCullFaceMode:3;  ///< cullface mode, 3 bits enough for 4 values
+  BlendingMode::Type mBlendingMode:2;  ///< blending mode, 2 bits enough for 3 values
+
+
 };
 
 } // namespace Internal
index abc78c9..ecba89e 100644 (file)
 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
 #include <dali/internal/event/animation/constraint-impl.h>
 #include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/common/property-owner-messages.h>
 #include <dali/internal/update/nodes/node-messages.h>
 #include <dali/internal/update/nodes/node-declarations.h>
 #include <dali/internal/update/animation/scene-graph-constraint.h>
-#include <dali/internal/event/effects/shader-effect-impl.h>
 #include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/internal/common/message.h>
 #include <dali/integration-api/debug.h>
@@ -61,7 +61,6 @@
 using Dali::Internal::SceneGraph::Node;
 using Dali::Internal::SceneGraph::AnimatableProperty;
 using Dali::Internal::SceneGraph::PropertyBase;
-using Dali::Internal::SceneGraph::Shader;
 
 using namespace std;
 
@@ -106,12 +105,11 @@ const Property::Index Actor::WORLD_MATRIX               = 34;
 const Property::Index Actor::NAME                       = 35;
 const Property::Index Actor::SENSITIVE                  = 36;
 const Property::Index Actor::LEAVE_REQUIRED             = 37;
-const Property::Index Actor::INHERIT_SHADER_EFFECT      = 38;
-const Property::Index Actor::INHERIT_ROTATION           = 39;
-const Property::Index Actor::INHERIT_SCALE              = 40;
-const Property::Index Actor::COLOR_MODE                 = 41;
-const Property::Index Actor::POSITION_INHERITANCE       = 42;
-const Property::Index Actor::DRAW_MODE                  = 43;
+const Property::Index Actor::INHERIT_ROTATION           = 38;
+const Property::Index Actor::INHERIT_SCALE              = 39;
+const Property::Index Actor::COLOR_MODE                 = 40;
+const Property::Index Actor::POSITION_INHERITANCE       = 41;
+const Property::Index Actor::DRAW_MODE                  = 42;
 
 namespace // unnamed namespace
 {
@@ -161,7 +159,6 @@ const Internal::PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
   { "name",                   Property::STRING,   true,    false,   false },  // NAME
   { "sensitive",              Property::BOOLEAN,  true,    false,   false },  // SENSITIVE
   { "leave-required",         Property::BOOLEAN,  true,    false,   false },  // LEAVE_REQUIRED
-  { "inherit-shader-effect",  Property::BOOLEAN,  true,    false,   false },  // INHERIT_SHADER_EFFECT
   { "inherit-rotation",       Property::BOOLEAN,  true,    false,   false },  // INHERIT_ROTATION
   { "inherit-scale",          Property::BOOLEAN,  true,    false,   false },  // INHERIT_SCALE
   { "color-mode",             Property::STRING,   true,    false,   false },  // COLOR_MODE
@@ -1118,77 +1115,18 @@ const Vector3& Actor::GetCurrentSize() const
   return Vector3::ZERO;
 }
 
-void Actor::SetInheritShaderEffect(bool inherit)
-{
-  if( NULL != mNode )
-  {
-    // mNode is being used in a separate thread; queue a message to set the value
-    SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
-  }
-}
-
-bool Actor::GetInheritShaderEffect() const
-{
-  if( NULL != mNode )
-  {
-    // mNode is being used in a separate thread; copy the value from the previous update
-    return mNode->GetInheritShader();
-  }
-
-  return true;
-}
-
 void Actor::SetShaderEffect(ShaderEffect& effect)
 {
-  if ( OnStage() )
-  {
-    if (mShaderEffect)
-    {
-      mShaderEffect->Disconnect();
-    }
-
-    mShaderEffect = ShaderEffectPtr(&effect);
-
-    const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
-
-    if( NULL != mNode )
-    {
-      // mNode is being used in a separate thread; queue a message to apply shader
-      ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
-    }
-
-    mShaderEffect->Connect();
-  }
-  else
-  {
-    mShaderEffect = ShaderEffectPtr(&effect);
-  }
-  // Effects can only be applied when the Node is connected to scene-graph
+  // no-op on an Actor
 }
 
 ShaderEffectPtr Actor::GetShaderEffect() const
 {
-  return mShaderEffect;
+  return ShaderEffectPtr();
 }
 
 void Actor::RemoveShaderEffect()
 {
-  if ( OnStage() )
-  {
-    if( NULL != mNode )
-    {
-      // mNode is being used in a separate thread; queue a message to remove shader
-      RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
-    }
-
-    // Notify shader effect
-    if (mShaderEffect)
-    {
-      mShaderEffect->Disconnect();
-    }
-  }
-
-  mShaderEffect.Reset();
 }
 
 #ifdef DYNAMICS_SUPPORT
@@ -2013,7 +1951,6 @@ Actor::Actor( DerivedType derivedType )
 #endif
   mGestureData( NULL ),
   mAttachment(),
-  mShaderEffect(),
   mName(),
   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
   mIsRoot( ROOT_LAYER == derivedType ),
@@ -2162,20 +2099,6 @@ void Actor::ConnectToSceneGraph()
     ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
   }
 
-  if (mShaderEffect)
-  {
-    const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
-
-    if( NULL != mNode )
-    {
-      // Effects can only be applied when the node is on-stage
-      ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
-    }
-
-    // Notify shader effect
-    mShaderEffect->Connect();
-  }
-
   // Notify attachment
   if (mAttachment)
   {
@@ -2270,12 +2193,6 @@ void Actor::DisconnectFromSceneGraph()
   // Notification for ProxyObject::Observers
   OnSceneObjectRemove();
 
-  // Notify shader effect
-  if (mShaderEffect)
-  {
-    mShaderEffect->Disconnect();
-  }
-
   // Notify attachment
   if (mAttachment)
   {
@@ -2613,12 +2530,6 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
       break;
     }
 
-    case Dali::Actor::INHERIT_SHADER_EFFECT:
-    {
-      SetInheritShaderEffect( property.Get<bool>() );
-      break;
-    }
-
     case Dali::Actor::INHERIT_ROTATION:
     {
       SetInheritRotation( property.Get<bool>() );
@@ -2988,12 +2899,6 @@ Property::Value Actor::GetDefaultProperty(Property::Index index) const
       break;
     }
 
-    case Dali::Actor::INHERIT_SHADER_EFFECT:
-    {
-      value = GetInheritShaderEffect();
-      break;
-    }
-
     case Dali::Actor::INHERIT_ROTATION:
     {
       value = IsRotationInherited();
index 75f5eac..e5de95b 100644 (file)
@@ -53,10 +53,10 @@ class Actor;
 class ActorGestureData;
 class RenderTask;
 class ShaderEffect;
+typedef IntrusivePtr<ShaderEffect>            ShaderEffectPtr;
 struct DynamicsData;
 
 typedef IntrusivePtr<Actor>                   ActorPtr;
-typedef IntrusivePtr<ShaderEffect>            ShaderEffectPtr;
 typedef Dali::ActorContainer                  ActorContainer; // Store handles to return via public-api
 typedef ActorContainer::iterator              ActorIter;
 typedef ActorContainer::const_iterator        ActorConstIter;
@@ -617,37 +617,30 @@ public:
     return mSensitive;
   }
 
-  /**
-   * Set whether the actor inherits a shader effect from its parent.
-   * The inherited effect can be overridden using SetShaderEffect()
-   * @param [in] inherit True if the parent effect is inherited.
-   */
-  void SetInheritShaderEffect(bool inherit);
-
-  /**
-   * Query whether the actor inherits a shader effect from its parent.
-   * @return True if the parent effect is inherited.
-   */
-  bool GetInheritShaderEffect() const;
+  // Shader effects, these are virtual so that RenderableActor can override the behaviour.
+  // Default actor behaviour is to do nothing, but the API is kept in Actor for convenience.
 
   /**
+   * @todo remove when API is cleaned up
    * Sets the shader effect for the Actor.
    * Shader effects provide special effects like rippling and bending.
    * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
    * @param [in] effect The shader effect.
    */
-  void SetShaderEffect(ShaderEffect& effect);
+  virtual void SetShaderEffect(ShaderEffect& effect);
 
   /**
+   * @todo remove when API is cleaned up
    * Retrieve the shader effect for the Actor.
    * @return The shader effect
    */
-  ShaderEffectPtr GetShaderEffect() const;
+  virtual ShaderEffectPtr GetShaderEffect() const;
 
   /**
+   * @todo remove when API is cleaned up
    * Removes the current shader effect.
    */
-  void RemoveShaderEffect();
+  virtual void RemoveShaderEffect();
 
   /**
    * @copydoc Dali::Actor::SetDrawMode
@@ -1324,10 +1317,9 @@ protected:
   DynamicsData*           mDynamicsData; ///< optional physics data
 #endif
 
-  ActorGestureData*            mGestureData; /// Optional Gesture data. Only created when actor requires gestures
+  ActorGestureData*       mGestureData; /// Optional Gesture data. Only created when actor requires gestures
 
   ActorAttachmentPtr      mAttachment;   ///< Optional referenced attachment
-  ShaderEffectPtr         mShaderEffect; ///< Optional referenced shader effect
 
   // Signals
   Dali::Actor::TouchSignalV2             mTouchedSignalV2;
index 82ca81a..dfaed7a 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/object/type-registry.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
 #include <dali/internal/event/actor-attachments/renderable-attachment-impl.h>
 
 namespace // unnamed namespace
@@ -138,6 +139,21 @@ RenderableActor::~RenderableActor()
 {
 }
 
+void RenderableActor::SetShaderEffect(ShaderEffect& effect)
+{
+  GetRenderableAttachment().SetShaderEffect( effect );
+}
+
+ShaderEffectPtr RenderableActor::GetShaderEffect() const
+{
+  return GetRenderableAttachment().GetShaderEffect();
+}
+
+void RenderableActor::RemoveShaderEffect()
+{
+  return GetRenderableAttachment().RemoveShaderEffect();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 8cfc9fb..8f7ef6e 100644 (file)
@@ -132,6 +132,23 @@ protected:
    */
   virtual ~RenderableActor();
 
+public: // from Actor, in future not virtual. Accessible also from RenderableActor
+
+  /**
+   * @copydoc Actor::SetShaderEffect
+   */
+  virtual void SetShaderEffect(ShaderEffect& effect);
+
+  /**
+   * @copydoc Actor::GetShaderEffect
+   */
+  virtual ShaderEffectPtr GetShaderEffect() const;
+
+  /**
+   * @copydoc Actor::RemoveShaderEffect
+   */
+  virtual void RemoveShaderEffect();
+
 private:
 
   /**
@@ -143,6 +160,7 @@ private:
   RenderableActor(const RenderableActor&);
   // Undefined
   RenderableActor& operator=(const RenderableActor& rhs);
+
 };
 
 } // namespace Internal
index 986b7e6..3bc444a 100644 (file)
@@ -34,12 +34,14 @@ SceneControllerImpl::SceneControllerImpl( RenderMessageDispatcher& renderMessage
                                           RenderQueue& renderQueue,
                                           DiscardQueue& discardQueue,
                                           TextureCache& textureCache,
-                                          CompleteStatusManager& completeStatusManager )
+                                          CompleteStatusManager& completeStatusManager,
+                                          Shader*& defaultShader )
 : mRenderMessageDispatcher( renderMessageDispatcher ),
   mRenderQueue( renderQueue ),
   mDiscardQueue( discardQueue ),
   mTextureCache( textureCache ),
-  mCompleteStatusManager( completeStatusManager )
+  mCompleteStatusManager( completeStatusManager ),
+  mDefaultShader( defaultShader )
 {
   mLightController  = new LightControllerImpl;
 }
index fb14658..9a62482 100644 (file)
@@ -46,52 +46,57 @@ public:
    * @param[in] renderQueue  The renderQueue
    * @param[in] discardQueue The discardQueue
    * @param[in] completeStatusTracker The resource complete status tracker
+   * @param[in] defaultShader to use for renderable attachments
    */
-  SceneControllerImpl( RenderMessageDispatcher& renderMessageDispatcher, RenderQueue& renderQueue, DiscardQueue& discardQueue, TextureCache& textureCache, CompleteStatusManager& completeStatusManager );
+  SceneControllerImpl( RenderMessageDispatcher& renderMessageDispatcher,
+                       RenderQueue& renderQueue,
+                       DiscardQueue& discardQueue,
+                       TextureCache& textureCache,
+                       CompleteStatusManager& completeStatusManager,
+                       Shader*& defaultShader );
 
   /**
    * Destructor
    */
   virtual ~SceneControllerImpl();
 
-public:  // for scene controller interface
+public:  // from SceneController
 
   /**
-   * Get the light  controller
-   * @return  reference to a light controller
+   * @copydoc SceneController::GetLightController()
    */
   virtual LightController& GetLightController() { return *mLightController; }
 
   /**
-   * Return the renderer dispatcher
-   * @return A reference to the renderer dispatcher
+   * @copydoc SceneController::GetRenderMessageDispatcher()
    */
   virtual RenderMessageDispatcher& GetRenderMessageDispatcher() { return mRenderMessageDispatcher; }
 
   /**
-   * Return the render queue
-   * @return A reference to the render queue
+   * @copydoc SceneController::GetRenderQueue()
    */
   virtual RenderQueue& GetRenderQueue() { return mRenderQueue; }
 
   /**
-   * Return the discard queue
-   * @return A reference to the discard queue
+   * @copydoc SceneController::GetDiscardQueue()
    */
   virtual DiscardQueue& GetDiscardQueue() { return mDiscardQueue; }
 
   /**
-   * Return the texture cache
-   * @note USE ONLY IN RENDER THREAD OBJECTS
-   * @return The texture cache
+   * @copydoc SceneController::GetTextureCache()
    */
   virtual TextureCache& GetTextureCache() { return mTextureCache; }
 
   /**
-   * @return the complete status tracker
+   * @copydoc SceneController::GetCompleteStatusManager()
    */
   virtual CompleteStatusManager& GetCompleteStatusManager() { return mCompleteStatusManager;  }
 
+  /**
+   * @copydoc SceneController::GetDefaultShader()
+   */
+  virtual Shader* GetDefaultShader() { return mDefaultShader; }
+
 private:
 
   // Undefined copy constructor.
@@ -102,12 +107,14 @@ private:
 
 private:
 
-  LightController*       mLightController;       ///< light controller
+  LightController*         mLightController;       ///< light controller
   RenderMessageDispatcher& mRenderMessageDispatcher;    ///< Used for passing messages to the render-thread
-  RenderQueue&           mRenderQueue;           ///< render queue
-  DiscardQueue&          mDiscardQueue;          ///< discard queue
-  TextureCache&          mTextureCache;          ///< texture cache
-  CompleteStatusManager& mCompleteStatusManager; ///< Complete Status manager
+  RenderQueue&             mRenderQueue;           ///< render queue
+  DiscardQueue&            mDiscardQueue;          ///< discard queue
+  TextureCache&            mTextureCache;          ///< texture cache
+  CompleteStatusManager&   mCompleteStatusManager; ///< Complete Status manager
+  Shader*&                 mDefaultShader;         ///< default shader, reference to a pointer as it will be setup later
+
 };
 
 } // namespace SceneGraph
index 39c05bc..72a4468 100644 (file)
@@ -34,6 +34,7 @@ class RenderMessageDispatcher;
 class RenderQueue;
 class DiscardQueue;
 class TextureCache;
+class Shader;
 
 /**
  * Abstract interface for the scene controller
@@ -95,6 +96,12 @@ public:
    */
   virtual CompleteStatusManager& GetCompleteStatusManager() = 0;
 
+  /**
+   * Return the default shader
+   * @return pointer to the default shader
+   */
+  virtual Shader* GetDefaultShader() = 0;
+
 private:
 
   // Undefined copy constructor.
index ce915c8..0c9e900 100644 (file)
@@ -31,7 +31,6 @@
 #include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
 #include <dali/internal/update/nodes/scene-graph-layer.h>
-#include <dali/internal/render/shaders/shader.h>
 #include <dali/internal/render/renderers/scene-graph-renderer.h>
 
 #include <dali/integration-api/debug.h>
@@ -110,24 +109,6 @@ unsigned int ConstrainNodes( Node& node, BufferIndex updateBufferIndex )
  ************************** Update node hierarchy *****************************
  ******************************************************************************/
 
-inline void UpdateRootNodeShader( Layer& rootNode, int nodeDirtyFlags, Shader* defaultShader )
-{
-  if ( nodeDirtyFlags & ShaderFlag )
-  {
-    rootNode.SetInheritedShader( defaultShader );
-  }
-}
-
-inline void UpdateNodeShader( Node& node, int nodeDirtyFlags, Shader* defaultShader )
-{
-  // If shader needs to be re-inherited
-  if ( nodeDirtyFlags & ShaderFlag )
-  {
-    // It will use the default if the nodes mInheritShader is set to false
-    node.InheritShader( defaultShader );
-  }
-}
-
 inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
 {
   if ( nodeDirtyFlags & ColorFlag )
@@ -331,12 +312,6 @@ inline RenderableAttachment* UpdateAttachment( NodeAttachment& attachment,
       renderable->SizeChanged( updateBufferIndex );
     }
 
-    // Notify renderables when shader has changed
-    if( nodeDirtyFlags & ShaderFlag )
-    {
-      renderable->ShaderChanged( updateBufferIndex );
-    }
-
     // check if node is visible
     if( renderable->ResolveVisibility( updateBufferIndex ) )
     {
@@ -365,7 +340,6 @@ inline int UpdateNodesAndAttachments( Node& node,
                                       ResourceManager& resourceManager,
                                       RenderQueue& renderQueue,
                                       Layer& currentLayer,
-                                      Shader* defaultShader,
                                       int inheritedDrawMode )
 {
   Layer* layer = &currentLayer;
@@ -387,11 +361,6 @@ inline int UpdateNodesAndAttachments( Node& node,
   // Some dirty flags are inherited from parent
   int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
 
-  if ( node.GetInheritedShader() == NULL )
-  {
-    nodeDirtyFlags |= ShaderFlag;
-  }
-
   int cumulativeDirtyFlags = nodeDirtyFlags;
 
   if ( node.IsLayer() )
@@ -407,8 +376,6 @@ inline int UpdateNodesAndAttachments( Node& node,
   }
   DALI_ASSERT_DEBUG( NULL != layer );
 
-  UpdateNodeShader( node, nodeDirtyFlags, defaultShader );
-
   UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
 
   UpdateNodeGeometry( node, nodeDirtyFlags, updateBufferIndex );
@@ -465,7 +432,6 @@ inline int UpdateNodesAndAttachments( Node& node,
                                                       resourceManager,
                                                       renderQueue,
                                                       *layer,
-                                                      defaultShader,
                                                       inheritedDrawMode );
   }
 
@@ -478,8 +444,7 @@ inline int UpdateNodesAndAttachments( Node& node,
 int UpdateNodesAndAttachments( Layer& rootNode,
                                BufferIndex updateBufferIndex,
                                ResourceManager& resourceManager,
-                               RenderQueue& renderQueue,
-                               Shader* defaultShader )
+                               RenderQueue& renderQueue )
 {
   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
 
@@ -499,15 +464,8 @@ int UpdateNodesAndAttachments( Layer& rootNode,
 
   int nodeDirtyFlags( rootNode.GetDirtyFlags() );
 
-  if ( rootNode.GetInheritedShader() == NULL )
-  {
-    nodeDirtyFlags |= ShaderFlag;
-  }
-
   int cumulativeDirtyFlags = nodeDirtyFlags;
 
-  UpdateRootNodeShader( rootNode, nodeDirtyFlags, defaultShader );
-
   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
 
   UpdateRootNodeTransformValues( rootNode, nodeDirtyFlags, updateBufferIndex );
@@ -526,7 +484,6 @@ int UpdateNodesAndAttachments( Layer& rootNode,
                                                        resourceManager,
                                                        renderQueue,
                                                        rootNode,
-                                                       defaultShader,
                                                        drawMode );
   }
 
index aac95a2..239d415 100644 (file)
@@ -36,7 +36,6 @@ class Layer;
 class Node;
 class PropertyOwner;
 class RenderQueue;
-class Shader;
 
 /**
  * Recursively apply the constraints on the nodes.
@@ -63,14 +62,12 @@ unsigned int ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex u
  * @param[in] updateBufferIndex The current update buffer index.
  * @param[in] resourceManager The resource manager.
  * @param[in] renderQueue Used to query messages for the next Render.
- * @param[in] defaultShader The default shader.
  * @return The cumulative (ORed) dirty flags for the updated nodes
  */
 int UpdateNodesAndAttachments( Layer& rootNode,
                                BufferIndex updateBufferIndex,
                                ResourceManager& resourceManager,
-                               RenderQueue& renderQueue,
-                               Shader* defaultShader );
+                               RenderQueue& renderQueue );
 
 } // namespace SceneGraph
 
index 3065a7a..f55da7f 100644 (file)
@@ -193,7 +193,7 @@ struct UpdateManager::Impl
     renderTaskList( NULL ),
     renderTaskWaiting( false )
   {
-    sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
+    sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager, defaultShader );
   }
 
   ~Impl()
@@ -951,26 +951,19 @@ void UpdateManager::UpdateNodes()
 
   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
 
-  Shader* defaultShader = GetDefaultShader();
+  // Prepare resources, update shaders, update attachments, for each node
+  // And add the renderers to the sorted layers. Start from root, which is also a layer
+  mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
+                                                     mSceneGraphBuffers.GetUpdateBufferIndex(),
+                                                     mImpl->resourceManager,
+                                                     mImpl->renderQueue );
 
-  if ( NULL != defaultShader )
+  if ( mImpl->systemLevelRoot )
   {
-    // Prepare resources, update shaders, update attachments, for each node
-    // And add the renderers to the sorted layers. Start from root, which is also a layer
-    mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
-                                                       mSceneGraphBuffers.GetUpdateBufferIndex(),
-                                                       mImpl->resourceManager,
-                                                       mImpl->renderQueue,
-                                                       defaultShader );
-
-    if ( mImpl->systemLevelRoot )
-    {
-      mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
-                                                          mSceneGraphBuffers.GetUpdateBufferIndex(),
-                                                          mImpl->resourceManager,
-                                                          mImpl->renderQueue,
-                                                          defaultShader );
-    }
+    mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
+                                                        mSceneGraphBuffers.GetUpdateBufferIndex(),
+                                                        mImpl->resourceManager,
+                                                        mImpl->renderQueue );
   }
 
   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
index 0edda1e..e0b4663 100644 (file)
@@ -190,22 +190,10 @@ void ImageAttachment::SetBorder( BufferIndex updateBufferIndex, const Vector4& b
 
 void ImageAttachment::ShaderChanged( BufferIndex updateBufferIndex )
 {
-  Shader* shader = GetParent().GetInheritedShader();
-  DALI_ASSERT_DEBUG( shader != NULL );
+  DALI_ASSERT_DEBUG( mShader != NULL );
   DALI_ASSERT_DEBUG( mSceneController );
 
-  // Use the Node's inherited shader in the next render
-  {
-    typedef MessageValue1< Renderer, Shader* > DerivedType;
-
-    // Reserve some memory inside the render queue
-    unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
-    // Construct message in the render queue memory; note that delete should not be called on the return value
-    new (slot) DerivedType( mImageRenderer, &Renderer::SetShader, shader );
-  }
-
-  int hints = shader->GetGeometryHints();
+  int hints = mShader->GetGeometryHints();
 
   if ( hints != mPreviousRefreshHints )
   {
@@ -331,7 +319,7 @@ bool ImageAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
    * Fully opaque when...
    *   1) not using the alpha channel from the image data
    *   2) the inherited color is not transparent nor semi-transparent
-   *   3) the shader doesn't require it
+   *   3) the shader doesn't require blending
    */
   bool opaque = mBitmapMetadata.IsFullyOpaque();
 
@@ -339,7 +327,7 @@ bool ImageAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
   {
     opaque = ( mParent->GetWorldColor(updateBufferIndex).a >= FULLY_OPAQUE );
 
-    if ( opaque && mParent->GetInheritedShader() != NULL )
+    if ( opaque && mShader != NULL )
     {
       opaque = !PreviousHintEnabled( Dali::ShaderEffect::HINT_BLENDING );
     }
index 786d881..11781d3 100644 (file)
@@ -119,27 +119,14 @@ const Renderer& MeshAttachment::GetRenderer() const
 void MeshAttachment::ShaderChanged( BufferIndex updateBufferIndex )
 {
   DALI_ASSERT_DEBUG(mSceneController);
-  Shader* shader = GetParent().GetInheritedShader();
 
-  {
-    typedef MessageValue1< Renderer, Shader* > DerivedType;
+  typedef Message< MeshRenderer > DerivedType;
 
-    // Reserve some memory inside the render queue
-    unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+  // Reserve some memory inside the render queue
+  unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
 
-    // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
-    new (slot) DerivedType( mRenderer, &Renderer::SetShader, shader );
-  }
-
-  {
-    typedef Message< MeshRenderer > DerivedType;
-
-    // Reserve some memory inside the render queue
-    unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
-    // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
-    new (slot) DerivedType( mRenderer, &MeshRenderer::ResetCustomUniforms );
-  }
+  // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
+  new (slot) DerivedType( mRenderer, &MeshRenderer::ResetCustomUniforms );
 }
 
 void MeshAttachment::SizeChanged( BufferIndex updateBufferIndex )
@@ -311,10 +298,9 @@ bool MeshAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
 
     if ( fullyOpaque )
     {
-      Shader* shader = mParent->GetInheritedShader();
-      if( shader != NULL )
+      if( mShader != NULL )
       {
-        fullyOpaque = (shader->GetGeometryHints() != Dali::ShaderEffect::HINT_BLENDING );
+        fullyOpaque = (mShader->GetGeometryHints() != Dali::ShaderEffect::HINT_BLENDING );
       }
     }
   }
index 03159e0..f903fbf 100644 (file)
@@ -108,9 +108,9 @@ void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, Reso
   mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
   mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
 
-  if( Shader* shader = mParent->GetAppliedShader() )
+  if( mShader )
   {
-    Integration::ResourceId id = shader->GetEffectTextureResourceId();
+    Integration::ResourceId id = mShader->GetEffectTextureResourceId();
 
     if( id != 0 )
     {
@@ -203,6 +203,29 @@ void RenderableAttachment::GetScaleForSize( const Vector3& nodeSize, Vector3& sc
   mScaleForSizeDirty = false;
 }
 
+void RenderableAttachment::ApplyShader( BufferIndex updateBufferIndex, Shader* shader )
+{
+  mShader = shader;
+
+  // send the message to renderer
+  SendShaderChangeMessage( updateBufferIndex );
+
+  // tell derived class to do something
+  ShaderChanged( updateBufferIndex );
+}
+
+void RenderableAttachment::RemoveShader( BufferIndex updateBufferIndex )
+{
+  // return to default shader
+  mShader = mSceneController->GetDefaultShader();
+
+  // send the message to renderer
+  SendShaderChangeMessage( updateBufferIndex );
+
+  // tell derived class to do something
+  ShaderChanged( updateBufferIndex );
+}
+
 void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
 {
   scaling = Vector3::ONE;
@@ -282,6 +305,9 @@ void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
 
 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
 : mSceneController(NULL),
+  mShader( NULL ),
+  mTrackedResources(),
+  mSortModifier( 0.0f ),
   mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
   mUsesGeometryScaling( usesGeometryScaling ),
   mScaleForSizeDirty( true ),
@@ -290,8 +316,7 @@ RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
   mResourcesReady( false ),
   mFinishedResourceAcquisition( false ),
   mHasUntrackedResources( false ),
-  mCullFaceMode( CullNone ),
-  mSortModifier( 0.0f )
+  mCullFaceMode( CullNone )
 {
 }
 
@@ -302,12 +327,18 @@ RenderableAttachment::~RenderableAttachment()
 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
 {
   mSceneController = &sceneController;
+  // get the default shader
+  mShader = mSceneController->GetDefaultShader();
 
   // Chain to derived attachments
   ConnectToSceneGraph2( updateBufferIndex );
 
   // After derived classes have (potentially) created their renderer
-  GetRenderer().SetCullFace( mCullFaceMode );
+  Renderer& renderer = GetRenderer();
+  renderer.SetCullFace( mCullFaceMode );
+
+  // set the default shader here as well
+  renderer.SetShader( mShader );
 }
 
 void RenderableAttachment::OnDestroy()
@@ -324,6 +355,14 @@ RenderableAttachment* RenderableAttachment::GetRenderable()
   return this;
 }
 
+void RenderableAttachment::SendShaderChangeMessage( BufferIndex updateBufferIndex )
+{
+  typedef MessageValue1< Renderer, Shader* > DerivedType;
+  // Reserve memory inside the render queue
+  unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+  // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
+  new (slot) DerivedType( &GetRenderer(), &Renderer::SetShader, mShader );
+}
 
 } // namespace SceneGraph
 
index 87477a5..3e35616 100644 (file)
@@ -42,6 +42,7 @@ class ResourceTracker;
 namespace SceneGraph
 {
 class Renderer;
+class Shader;
 
 /**
  * RenderableAttachments are responsible for preparing textures, meshes, matrices etc. during the Update.
@@ -143,6 +144,19 @@ public: // API
    */
   void GetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
 
+  /**
+   * Apply a shader on the renderable
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] shader to apply.
+   */
+  void ApplyShader( BufferIndex updateBufferIndex, Shader* shader );
+
+  /**
+   * Remove the shader from the renderable
+   * @param[in] updateBufferIndex The current update buffer index.
+   */
+  void RemoveShader( BufferIndex updateBufferIndex );
+
 public: // For use during in the update algorithm only
 
   /**
@@ -319,6 +333,12 @@ private:
    */
   virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
 
+  /**
+   * Sends the shader to the renderer
+   * @param updateBufferIndex for the message buffer
+   */
+  void SendShaderChangeMessage( BufferIndex updateBufferIndex );
+
   // Undefined
   RenderableAttachment( const RenderableAttachment& );
 
@@ -328,8 +348,13 @@ private:
 protected:
 
   SceneController* mSceneController;   ///< Used for initializing renderers whilst attached
+  Shader*          mShader;            ///< A pointer to the shader
 
-  BlendingMode::Type mBlendingMode:2;    ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
+  Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
+
+  float mSortModifier;
+
+  BlendingMode::Type mBlendingMode:2;  ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
 
   bool mUsesGeometryScaling:1;         ///< True if the derived renderer uses scaling.
   bool mScaleForSizeDirty:1;           ///< True if mScaleForSize has changed in the current frame.
@@ -340,9 +365,6 @@ protected:
   bool mHasUntrackedResources:1;       ///< Set during PrepareResources, true if have tried to follow untracked resources
   CullFaceMode mCullFaceMode:3;        ///< Cullface mode, 3 bits is enough for 4 values
 
-  float mSortModifier;
-
-  Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
 };
 
 // Messages for RenderableAttachment
@@ -410,6 +432,31 @@ inline void SetSamplerMessage( EventToUpdate& eventToUpdate, const RenderableAtt
   new (slot) LocalType( &attachment, &RenderableAttachment::SetSampler, samplerBitfield );
 }
 
+inline void ApplyShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, const Shader& constShader )
+{
+  // Update thread can edit the object
+  Shader& shader = const_cast< Shader& >( constShader );
+
+  typedef MessageDoubleBuffered1< RenderableAttachment, Shader* > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &attachment, &RenderableAttachment::ApplyShader, &shader );
+}
+
+inline void RemoveShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment )
+{
+  typedef MessageDoubleBuffered0< RenderableAttachment > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &attachment, &RenderableAttachment::RemoveShader );
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 9191993..ae81d64 100644 (file)
@@ -211,17 +211,7 @@ void TextAttachment::SetSmoothEdge( BufferIndex updateBufferIndex, const float p
 
 void TextAttachment::ShaderChanged( BufferIndex updateBufferIndex )
 {
-  {
-    Shader* shader = GetParent().GetInheritedShader();
-
-    typedef MessageValue1< Renderer, Shader* > DerivedType;
-
-    // Reserve some memory inside the render queue
-    unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
-    // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
-    new (slot) DerivedType( mTextRenderer, &Renderer::SetShader, shader );
-  }
+  // nothing to do
 }
 
 void TextAttachment::SizeChanged( BufferIndex updateBufferIndex )
index 922e0f5..0dd87c1 100644 (file)
@@ -21,7 +21,6 @@
 // INTERNAL INCLUDES
 #include <dali/internal/update/node-attachments/node-attachment.h>
 #include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/render/shaders/shader.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/constants.h>
 
@@ -57,8 +56,6 @@ Node::Node()
   mWorldMatrix( Matrix::IDENTITY ),
   mWorldColor( Color::WHITE ),
   mParent( NULL ),
-  mAppliedShader( NULL ),
-  mInheritedShader( NULL ),
   mExclusiveRenderTask( NULL ),
   mAttachment( NULL ),
   mChildren(),
@@ -66,7 +63,6 @@ Node::Node()
   mInitialVolume( Vector3::ONE ),
   mDirtyFlags(AllFlags),
   mIsRoot( false ),
-  mInheritShader( true ),
   mInheritRotation( true ),
   mInheritScale( true ),
   mTransmitGeometryScaling( false ),
@@ -149,61 +145,6 @@ void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std:
   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
 }
 
-void Node::ApplyShader( Shader* shader )
-{
-  DALI_ASSERT_DEBUG( shader && "null shader passed to node" );
-
-  mAppliedShader = shader;
-
-  SetDirtyFlag(ShaderFlag);
-}
-
-void Node::RemoveShader()
-{
-  mAppliedShader = NULL; // Wait until InheritShader to grab default shader
-
-  SetDirtyFlag(ShaderFlag);
-}
-
-Shader* Node::GetAppliedShader() const
-{
-  return mAppliedShader;
-}
-
-void Node::SetInheritedShader(Shader* shader)
-{
-  mInheritedShader = shader;
-}
-
-Shader* Node::GetInheritedShader() const
-{
-  return mInheritedShader;
-}
-
-void Node::InheritShader(Shader* defaultShader)
-{
-  DALI_ASSERT_DEBUG(mParent != NULL);
-
-  // If we have a custom shader for this node, then use it
-  if ( mAppliedShader != NULL )
-  {
-    mInheritedShader = mAppliedShader;
-  }
-  else
-  {
-    // Otherwise we either inherit a shader, or fall-back to the default
-    if (mInheritShader)
-    {
-      mInheritedShader = mParent->GetInheritedShader();
-    }
-    else
-    {
-      mInheritedShader = defaultShader;
-    }
-  }
-  DALI_ASSERT_DEBUG( mInheritedShader != NULL );
-}
-
 int Node::GetDirtyFlags() const
 {
   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
@@ -306,10 +247,6 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std
   // Animators, Constraints etc. should be disconnected from the child's properties.
   PropertyOwner::DisconnectFromSceneGraph();
 
-  // Remove effects
-  mAppliedShader         = NULL;
-  mInheritedShader       = NULL;
-
   // Remove back-pointer to parent
   mParent = NULL;
 
index 099420d..c28e2ea 100644 (file)
@@ -52,7 +52,6 @@ namespace SceneGraph
 
 class DiscardQueue;
 class Layer;
-class Shader;
 class NodeAttachment;
 class RenderTask;
 class UpdateManager;
@@ -67,10 +66,9 @@ enum NodePropertyFlags
   VisibleFlag          = 0x002,
   ColorFlag            = 0x004,
   SizeFlag             = 0x008,
-  ShaderFlag           = 0x010,
-  OverlayFlag          = 0x020,
-  SortModifierFlag     = 0x040,
-  ChildDeletedFlag     = 0x080
+  OverlayFlag          = 0x010,
+  SortModifierFlag     = 0x020,
+  ChildDeletedFlag     = 0x040
 };
 
 static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
@@ -79,7 +77,7 @@ static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
  * Size is not inherited.
  * VisibleFlag is inherited so that attachments can be synchronized with nodes after they become visible
  */
-static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | ShaderFlag | OverlayFlag;
+static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | OverlayFlag;
 
 // Flags which require the scene renderable lists to be updated
 static const int RenderableUpdateFlags = TransformFlag | SortModifierFlag | ChildDeletedFlag;
@@ -257,70 +255,6 @@ public:
     return mChildren;
   }
 
-  // Shaders
-
-  /**
-   * Set whether the node inherits a shader effect from its parent.
-   * The inherited effect can be overriden using ApplyShader()
-   * @param [in] inherit True if the parent effect is inherited.
-   */
-  void SetInheritShader(bool inherit)
-  {
-    if (inherit != mInheritShader)
-    {
-      mInheritShader = inherit;
-
-      SetDirtyFlag(ShaderFlag);
-    }
-  }
-
-  /**
-   * Query whether the node inherits a shader from its parent.
-   * @return True if the parent effect is inherited.
-   */
-  bool GetInheritShader() const
-  {
-    return mInheritShader;
-  }
-
-  /**
-   * Apply a shader object to this Node.
-   * Shader effects are weakly referenced, potentially by multiple nodes & node attachments.
-   * @param[in] shader The shader to apply.
-   */
-  void ApplyShader( Shader* shader );
-
-  /**
-   * Remove the shader object from this Node (if any).
-   */
-  void RemoveShader();
-
-  /**
-   * Retrieve the applied shader.
-   * @return The applied shader.
-   */
-  Shader* GetAppliedShader() const;
-
-  /**
-   * Sets the inherited shader of the node.
-   * @param[in] shader The new inherited shader.
-   */
-  void SetInheritedShader(Shader* shader);
-
-  /**
-   * Retrieve the inherited shader.
-   * @return The inherited shader.
-   */
-  Shader* GetInheritedShader() const;
-
-  /**
-   * Inherit a shader (if any) applied to the parent node.
-   * This method should only be called when the parents inherited shader is up-to-date.
-   * @param defaultShader pointer to the default shader, used if inherit shader is set to false
-   * @pre The node has a parent.
-   */
-  void InheritShader(Shader* defaultShader);
-
   // Update methods
 
   /**
@@ -1116,8 +1050,6 @@ public: // Default properties
 protected:
 
   Node*               mParent;                       ///< Pointer to parent node (a child is owned by its parent)
-  Shader*             mAppliedShader;                ///< A pointer to an applied shader
-  Shader*             mInheritedShader;              ///< A pointer to an inherited shader
   RenderTask*         mExclusiveRenderTask;          ///< Nodes can be marked as exclusive to a single RenderTask
 
   NodeAttachmentOwner mAttachment;                   ///< Optional owned attachment
@@ -1130,7 +1062,6 @@ protected:
   int  mDirtyFlags:10;                               ///< A composite set of flags for each of the Node properties
 
   bool mIsRoot:1;                                    ///< True if the node cannot have a parent
-  bool mInheritShader:1;                             ///< Whether the parent's shader should be inherited.
   bool mInheritRotation:1;                           ///< Whether the parent's rotation should be inherited.
   bool mInheritScale:1;                              ///< Whether the parent's scale should be inherited.
   bool mTransmitGeometryScaling:1;                   ///< Whether geometry scaling should be applied to world transform.
@@ -1147,17 +1078,6 @@ protected:
 
 // Messages for Node
 
-inline void SetInheritShaderMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
-{
-  typedef MessageValue1< Node, bool > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &node, &Node::SetInheritShader, inherit );
-}
-
 inline void SetInheritRotationMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
 {
   typedef MessageValue1< Node, bool > LocalType;
@@ -1191,31 +1111,6 @@ inline void SetTransmitGeometryScalingMessage( EventToUpdate& eventToUpdate, con
   new (slot) LocalType( &node, &Node::SetTransmitGeometryScaling, transmitGeometryScaling );
 }
 
-inline void ApplyShaderMessage( EventToUpdate& eventToUpdate, const Node& node, const Shader& constShader )
-{
-  // Update thread can edit the object
-  Shader& shader = const_cast< Shader& >( constShader );
-
-  typedef MessageValue1< Node, Shader* > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &node, &Node::ApplyShader, &shader );
-}
-
-inline void RemoveShaderMessage( EventToUpdate& eventToUpdate, const Node& node )
-{
-  typedef Message< Node > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &node, &Node::RemoveShader );
-}
-
 inline void SetParentOriginMessage( EventToUpdate& eventToUpdate, const Node& node, const Vector3& origin )
 {
   typedef MessageValue1< Node, Vector3 > LocalType;
index ee1f765..58214dd 100644 (file)
@@ -434,28 +434,32 @@ Vector4 Actor::GetCurrentWorldColor() const
 
 void Actor::SetInheritShaderEffect(bool inherit)
 {
-  GetImplementation(*this).SetInheritShaderEffect(inherit);
+  // TODO remove this API
+  // @deprecated
 }
 
 bool Actor::GetInheritShaderEffect() const
 {
-  return GetImplementation(*this).GetInheritShaderEffect();
+  // TODO remove this API
+  // @deprecated
+  return false;
 }
 
 void Actor::SetShaderEffect(ShaderEffect effect)
 {
+  // TODO remove this API
   GetImplementation(*this).SetShaderEffect(GetImplementation(effect));
 }
 
 ShaderEffect Actor::GetShaderEffect() const
 {
-  Internal::ShaderEffectPtr internal = GetImplementation(*this).GetShaderEffect();
-
-  return ShaderEffect(internal.Get());
+  // TODO remove this API
+  return ShaderEffect();
 }
 
 void Actor::RemoveShaderEffect()
 {
+  // TODO remove this API
   GetImplementation(*this).RemoveShaderEffect();
 }
 
index 288dfad..2b48505 100644 (file)
@@ -260,7 +260,6 @@ public:
   static const Property::Index NAME;                  ///< name "name",                  type STRING
   static const Property::Index SENSITIVE;             ///< name "sensitive",             type BOOLEAN
   static const Property::Index LEAVE_REQUIRED;        ///< name "leave-required",        type BOOLEAN
-  static const Property::Index INHERIT_SHADER_EFFECT; ///< name "inherit-shader-effect", type BOOLEAN
   static const Property::Index INHERIT_ROTATION;      ///< name "inherit-rotation",      type BOOLEAN
   static const Property::Index INHERIT_SCALE;         ///< name "inherit-scale",         type BOOLEAN
   static const Property::Index COLOR_MODE;            ///< name "color-mode",            type STRING
@@ -405,7 +404,7 @@ public:
    * @brief Adds a child Actor to this Actor.
    *
    * NOTE! if the child already has a parent, it will be removed from old parent
-   * and reparented to this actor. This may change childs position, color, shader effect,
+   * and reparented to this actor. This may change childs position, color,
    * scale etc as it now inherits them from this actor
    * @pre This Actor (the parent) has been initialized.
    * @pre The child actor has been initialized.
@@ -991,45 +990,35 @@ public:
   // Shader Effects
 
   /**
-   * @brief Set whether the actor inherits a shader effect from its parent; it does inherit by default.
+   * @deprecated call Set/RemoveShaderEffectRecursively if you want to apply the same shader for a tree of actors
    *
-   * The inherited effect can still be overriden using SetShaderEffect().
-   * @pre The Actor has been initialized.
-   * @param [in] inherit True if the parent effect is inherited.
+   * @param [in] ignored
    */
-  void SetInheritShaderEffect(bool inherit);
+  void SetInheritShaderEffect(bool ignored);
 
   /**
-   * @brief Query whether the actor inherits a shader effect from its parent.
+   * @deprecated functionality no longer supported
    *
-   * @pre The Actor has been initialized.
-   * @return True if the parent effect is inherited.
+   * @return false
    */
   bool GetInheritShaderEffect() const;
 
   /**
-   * @brief Sets the shader effect for the Actor.
+   * @deprecated you need to call RenderableActor::SetShaderEffect
    *
-   * Shader effects provide special effects like rippling and bending.
-   * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
-   * @pre The actor has been initialized.
-   * @pre effect has been initialized.
    * @param [in] effect The shader effect.
    */
   void SetShaderEffect(ShaderEffect effect);
 
   /**
-   * @brief Retrieve the shader effect for the Actor.
+   * @deprecated you need to call RenderableActor::GetShaderEffect
    *
-   * @pre The Actor has been initialized.
    * @return The shader effect
    */
   ShaderEffect GetShaderEffect() const;
 
   /**
-   * @brief Removes the current shader effect.
-   *
-   * @pre The Actor has been initialized.
+   * @deprecated you need to call RenderableActor::GetShaderEffect
    */
   void RemoveShaderEffect();
 
index 466a5d9..0f72467 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/event/actors/renderable-actor-impl.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
 
 namespace Dali
 {
@@ -139,9 +140,68 @@ void RenderableActor::GetFilterMode( FilterMode::Type& minFilter, FilterMode::Ty
   GetImplementation(*this).GetFilterMode( minFilter, magFilter );
 }
 
+void RenderableActor::SetShaderEffect(ShaderEffect effect)
+{
+  GetImplementation(*this).SetShaderEffect(GetImplementation(effect));
+}
+
+ShaderEffect RenderableActor::GetShaderEffect() const
+{
+  Internal::ShaderEffectPtr internal = GetImplementation(*this).GetShaderEffect();
+
+  return ShaderEffect(internal.Get());
+}
+
+void RenderableActor::RemoveShaderEffect()
+{
+  GetImplementation(*this).RemoveShaderEffect();
+}
+
 RenderableActor::RenderableActor(Internal::RenderableActor* internal)
 : Actor(internal)
 {
 }
 
+void SetShaderEffectRecursively( Actor actor, ShaderEffect effect )
+{
+  // only do something if the actor and effect are valid
+  if( actor && effect )
+  {
+    // first remove from this actor
+    RenderableActor renderable = RenderableActor::DownCast( actor );
+    if( renderable )
+    {
+      renderable.SetShaderEffect( effect );
+    }
+    // then all children recursively
+    const unsigned int count = actor.GetChildCount();
+    for( unsigned int index = 0; index < count; ++index )
+    {
+      Actor child( actor.GetChildAt( index ) );
+      SetShaderEffectRecursively( child, effect );
+    }
+  }
+}
+
+void RemoveShaderEffectRecursively( Actor actor )
+{
+  // only do something if the actor is valid
+  if( actor )
+  {
+    // first remove from this actor
+    RenderableActor renderable = RenderableActor::DownCast( actor );
+    if( renderable )
+    {
+      renderable.RemoveShaderEffect();
+    }
+    // then all children recursively
+    const unsigned int count = actor.GetChildCount();
+    for( unsigned int index = 0; index < count; ++index )
+    {
+      Actor child( actor.GetChildAt( index ) );
+      RemoveShaderEffectRecursively( child );
+    }
+  }
+}
+
 } // namespace Dali
index 1fccaeb..8206c25 100644 (file)
@@ -266,6 +266,33 @@ public:
    */
   void GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter) const;
 
+  /**
+   * @brief Sets the shader effect for the RenderableActor.
+   *
+   * Shader effects provide special effects like ripple and bend.
+   * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
+   * @pre The actor has been initialized.
+   * @pre effect has been initialized.
+   * @param [in] effect The shader effect.
+   */
+  void SetShaderEffect( ShaderEffect effect );
+
+  /**
+   * @brief Retrieve the custom shader effect for the RenderableActor.
+   * If default shader is used an empty handle is returned.
+   *
+   * @pre The Actor has been initialized.
+   * @return The shader effect
+   */
+  ShaderEffect GetShaderEffect() const;
+
+  /**
+   * @brief Removes the current shader effect.
+   *
+   * @pre The Actor has been initialized.
+   */
+  void RemoveShaderEffect();
+
 public: // Not intended for application developers
 
   /**
@@ -276,6 +303,25 @@ public: // Not intended for application developers
   explicit DALI_INTERNAL RenderableActor(Internal::RenderableActor* actor);
 };
 
+/**
+ * @brief Sets the shader effect for all RenderableActors in a tree of Actors.
+ *
+ * @see RenderableActor::SetShaderEffect
+ *
+ * @param [in] actor root of a tree of actors.
+ * @param [in] effect The shader effect.
+ */
+void SetShaderEffectRecursively( Actor actor, ShaderEffect effect );
+
+/**
+ * @brief Removes the shader effect from all RenderableActors in a tree of Actors.
+ *
+ * @see RenderableActor::RemoveShaderEffect
+ *
+ * @param [in] actor root of a tree of actors.
+ */
+void RemoveShaderEffectRecursively( Actor actor );
+
 } // namespace Dali
 
 #endif // __DALI_RENDERABLE_ACTOR_H__