From: Kimmo Hoikka Date: Mon, 4 Aug 2014 16:46:10 +0000 (+0100) Subject: removal of shader inheritance, renderable actors now have shaders and there is a... X-Git-Tag: dali_1.0.5~10^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2edd07c4c9b35c48c5c33cb48bea6b04a7e74a5f;p=platform%2Fcore%2Fuifw%2Fdali-core.git removal of shader inheritance, renderable actors now have shaders and there is a recursive setter requires https://review.tizen.org/gerrit/#/c/25510/ [Problem] [Cause] [Solution] Change-Id: I09f525cfe6ba34068ab6c1ae8bd247744eb7d272 --- diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 2a3342d37..d810d079b 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -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 }, diff --git a/automated-tests/src/dali/utc-Dali-Handle.cpp b/automated-tests/src/dali/utc-Dali-Handle.cpp index 8ff666bf1..1747227ad 100644 --- a/automated-tests/src/dali/utc-Dali-Handle.cpp +++ b/automated-tests/src/dali/utc-Dali-Handle.cpp @@ -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 ) ); diff --git a/automated-tests/src/dali/utc-Dali-RenderableActor.cpp b/automated-tests/src/dali/utc-Dali-RenderableActor.cpp index 5eaea3680..dfea42840 100644 --- a/automated-tests/src/dali/utc-Dali-RenderableActor.cpp +++ b/automated-tests/src/dali/utc-Dali-RenderableActor.cpp @@ -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; +} + diff --git a/dali/internal/common/message.h b/dali/internal/common/message.h index 13c67bbb4..201186c82 100644 --- a/dali/internal/common/message.h +++ b/dali/internal/common/message.h @@ -543,6 +543,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. diff --git a/dali/internal/event/actor-attachments/renderable-attachment-impl.cpp b/dali/internal/event/actor-attachments/renderable-attachment-impl.cpp index 84d4d718a..80a2a2758 100644 --- a/dali/internal/event/actor-attachments/renderable-attachment-impl.cpp +++ b/dali/internal/event/actor-attachments/renderable-attachment-impl.cpp @@ -20,8 +20,10 @@ // INTERNAL INCLUDES #include +#include #include -#include + +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( *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( *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(); } diff --git a/dali/internal/event/actor-attachments/renderable-attachment-impl.h b/dali/internal/event/actor-attachments/renderable-attachment-impl.h index 5900e7149..4c48c8a1c 100644 --- a/dali/internal/event/actor-attachments/renderable-attachment-impl.h +++ b/dali/internal/event/actor-attachments/renderable-attachment-impl.h @@ -35,6 +35,8 @@ namespace SceneGraph { class RenderableAttachment; } +class ShaderEffect; +typedef IntrusivePtr 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 diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index abc78c9d8..ecba89e7e 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -41,12 +41,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -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( *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( *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() ); - break; - } - case Dali::Actor::INHERIT_ROTATION: { SetInheritRotation( property.Get() ); @@ -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(); diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 75f5eac05..e5de95bf9 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -53,10 +53,10 @@ class Actor; class ActorGestureData; class RenderTask; class ShaderEffect; +typedef IntrusivePtr ShaderEffectPtr; struct DynamicsData; typedef IntrusivePtr ActorPtr; -typedef IntrusivePtr 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; diff --git a/dali/internal/event/actors/renderable-actor-impl.cpp b/dali/internal/event/actors/renderable-actor-impl.cpp index 82ca81ac2..dfaed7a29 100644 --- a/dali/internal/event/actors/renderable-actor-impl.cpp +++ b/dali/internal/event/actors/renderable-actor-impl.cpp @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include #include 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 diff --git a/dali/internal/event/actors/renderable-actor-impl.h b/dali/internal/event/actors/renderable-actor-impl.h index 8cfc9fb0a..8f7ef6e0f 100644 --- a/dali/internal/event/actors/renderable-actor-impl.h +++ b/dali/internal/event/actors/renderable-actor-impl.h @@ -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 diff --git a/dali/internal/update/controllers/scene-controller-impl.cpp b/dali/internal/update/controllers/scene-controller-impl.cpp index 986b7e673..3bc444a0a 100644 --- a/dali/internal/update/controllers/scene-controller-impl.cpp +++ b/dali/internal/update/controllers/scene-controller-impl.cpp @@ -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; } diff --git a/dali/internal/update/controllers/scene-controller-impl.h b/dali/internal/update/controllers/scene-controller-impl.h index fb146583e..9a6248295 100644 --- a/dali/internal/update/controllers/scene-controller-impl.h +++ b/dali/internal/update/controllers/scene-controller-impl.h @@ -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 diff --git a/dali/internal/update/controllers/scene-controller.h b/dali/internal/update/controllers/scene-controller.h index 39c05bc5a..72a446862 100644 --- a/dali/internal/update/controllers/scene-controller.h +++ b/dali/internal/update/controllers/scene-controller.h @@ -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. diff --git a/dali/internal/update/manager/update-algorithms.cpp b/dali/internal/update/manager/update-algorithms.cpp index ce915c873..0c9e90065 100644 --- a/dali/internal/update/manager/update-algorithms.cpp +++ b/dali/internal/update/manager/update-algorithms.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -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 = ¤tLayer; @@ -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 ); } diff --git a/dali/internal/update/manager/update-algorithms.h b/dali/internal/update/manager/update-algorithms.h index aac95a295..239d415d6 100644 --- a/dali/internal/update/manager/update-algorithms.h +++ b/dali/internal/update/manager/update-algorithms.h @@ -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 diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 3065a7a71..f55da7fed 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -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 ); diff --git a/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp index 0edda1ea6..e0b4663c5 100644 --- a/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp @@ -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 ); } diff --git a/dali/internal/update/node-attachments/scene-graph-mesh-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-mesh-attachment.cpp index 786d881a0..11781d340 100644 --- a/dali/internal/update/node-attachments/scene-graph-mesh-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-mesh-attachment.cpp @@ -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 ); } } } diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp index 03159e0ff..f903fbf53 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp @@ -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 diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h index 87477a5d2..3e356168a 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h @@ -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 diff --git a/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp index 919199394..ae81d6499 100644 --- a/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-text-attachment.cpp @@ -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 ) diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 922e0f5f8..0dd87c1b2 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -21,7 +21,6 @@ // INTERNAL INCLUDES #include #include -#include #include #include @@ -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; diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 099420d95..c28e2ea18 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -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; diff --git a/dali/public-api/actors/actor.cpp b/dali/public-api/actors/actor.cpp index ee1f76531..58214ddfe 100644 --- a/dali/public-api/actors/actor.cpp +++ b/dali/public-api/actors/actor.cpp @@ -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(); } diff --git a/dali/public-api/actors/actor.h b/dali/public-api/actors/actor.h index 288dfadfc..2b48505dd 100644 --- a/dali/public-api/actors/actor.h +++ b/dali/public-api/actors/actor.h @@ -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(); diff --git a/dali/public-api/actors/renderable-actor.cpp b/dali/public-api/actors/renderable-actor.cpp index 466a5d930..0f7246726 100644 --- a/dali/public-api/actors/renderable-actor.cpp +++ b/dali/public-api/actors/renderable-actor.cpp @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include 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 diff --git a/dali/public-api/actors/renderable-actor.h b/dali/public-api/actors/renderable-actor.h index 1fccaeb62..8206c2593 100644 --- a/dali/public-api/actors/renderable-actor.h +++ b/dali/public-api/actors/renderable-actor.h @@ -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__