From b154e74ada0754b5b47adcdffcf4a70df43ebbec Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Thu, 17 Dec 2015 16:52:15 +0000 Subject: [PATCH] Stop using ImageActor in EffectsView and ImageFilters Change-Id: Icc8793ab46b8e6c10a5f10bace53304b5f7d26b0 --- .../src/dali-toolkit/utc-Dali-EffectsView.cpp | 363 ++++++----------- .../controls/effects-view/effects-view.cpp | 51 +-- .../devel-api/controls/effects-view/effects-view.h | 94 ++--- .../controls/effects-view/effects-view-impl.cpp | 442 +++++++++++---------- .../controls/effects-view/effects-view-impl.h | 138 +++---- .../internal/filters/blur-two-pass-filter.cpp | 147 +++---- .../internal/filters/blur-two-pass-filter.h | 34 +- dali-toolkit/internal/filters/emboss-filter.cpp | 189 +++------ dali-toolkit/internal/filters/emboss-filter.h | 30 +- dali-toolkit/internal/filters/image-filter.cpp | 26 +- dali-toolkit/internal/filters/image-filter.h | 11 +- dali-toolkit/internal/filters/spread-filter.cpp | 84 ++-- dali-toolkit/internal/filters/spread-filter.h | 24 +- 13 files changed, 665 insertions(+), 968 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp index a6be471..09b51f2 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp @@ -42,11 +42,15 @@ int UtcDaliEffectsViewNew(void) EffectsView view; DALI_TEST_CHECK( !view ); - view = EffectsView::New(); + view = EffectsView::New( EffectsView::DROP_SHADOW ); DALI_TEST_CHECK( view ); Stage::GetCurrent().Add( view ); + view.Reset(); + view = EffectsView::New( EffectsView::EMBOSS ); + DALI_TEST_CHECK( view ); + application.SendNotification(); application.Render(); @@ -57,7 +61,7 @@ int UtcDaliEffectsViewCopyAndAssignment(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); DALI_TEST_CHECK( view ); EffectsView copy( view ); @@ -80,7 +84,7 @@ int UtcDaliEffectsViewDownCast(void) { ToolkitTestApplication application; - BaseHandle view = EffectsView::New(); + BaseHandle view = EffectsView::New( EffectsView::EMBOSS ); DALI_TEST_CHECK( EffectsView::DownCast( view ) ); BaseHandle empty; @@ -92,131 +96,92 @@ int UtcDaliEffectsViewDownCast(void) END_TEST; } -int UtcDaliEffectsViewSetGetTypeP(void) +// Positive test case for a method +int UtcDaliEffectsViewAddRemove(void) { ToolkitTestApplication application; + tet_infoline("UtcDaliGaussianBlurViewAddRemove"); - EffectsView view = EffectsView::New(); - DALI_TEST_CHECK( view.GetType() == EffectsView::INVALID_TYPE ); + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); + DALI_TEST_CHECK( view ); - view.SetType( EffectsView::DROP_SHADOW ); - DALI_TEST_CHECK( view.GetType() == EffectsView::DROP_SHADOW ); + Actor actor = Actor::New(); + DALI_TEST_CHECK( !actor.OnStage() ); - view.SetType( EffectsView::EMBOSS ); - DALI_TEST_CHECK( view.GetType() == EffectsView::EMBOSS ); - END_TEST; -} + view.SetParentOrigin(ParentOrigin::CENTER); + view.SetSize(Stage::GetCurrent().GetSize()); + view.Add(actor); + Stage::GetCurrent().Add(view); -int UtcDaliEffectsViewSetTypeN(void) -{ - ToolkitTestApplication application; + DALI_TEST_CHECK( actor.OnStage() ); + DALI_TEST_CHECK( actor.GetParent() ); + DALI_TEST_CHECK( actor.GetParent() != view ); - EffectsView view; - try - { - view.SetType( EffectsView::DROP_SHADOW ); - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } + view.Remove(actor); + DALI_TEST_CHECK( !actor.OnStage() ); END_TEST; } -int UtcDaliEffectsViewGetTypeN(void) +int UtcDaliEffectsViewGetTypeP(void) { ToolkitTestApplication application; - EffectsView view; - try - { - EffectsView::EffectType type = view.GetType(); - (void) type; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); + DALI_TEST_CHECK( view.GetType() == EffectsView::DROP_SHADOW ); + + view.Reset(); + view = EffectsView::New( EffectsView::EMBOSS ); + DALI_TEST_CHECK( view.GetType() == EffectsView::EMBOSS ); END_TEST; } -int UtcDaliEffectsViewEnableP(void) +int UtcDaliEffectsViewOnStage(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New(EffectsView::EMBOSS); + view.SetSize(100.f, 100.f); Stage stage = Stage::GetCurrent(); DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 ); - view.Enable(); + stage.Add( view ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() > 1 ); END_TEST; } -int UtcDaliEffectsViewEnableN(void) +int UtcDaliEffectsViewOffStage(void) { ToolkitTestApplication application; - EffectsView view; - try - { - view.Enable(); - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} - -int UtcDaliEffectsViewDisableP(void) -{ - ToolkitTestApplication application; - - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW); + view.SetSize(100.f, 100.f); Stage stage = Stage::GetCurrent(); DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 ); - view.Enable(); + stage.Add( view ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() > 1 ); - view.Disable(); + stage.Remove( view ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 ); END_TEST; } -int UtcDaliEffectsViewDisableN(void) -{ - ToolkitTestApplication application; - - EffectsView view; - try - { - view.Disable(); - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} - int UtcDaliEffectsViewRefreshP(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); try { view.Refresh(); @@ -252,7 +217,7 @@ int UtcDaliEffectsViewSetPixelFormatP(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); try { view.SetPixelFormat( Pixel::RGBA8888 ); @@ -284,179 +249,90 @@ int UtcDaliEffectsViewSetPixelFormatN(void) END_TEST; } -int UtcDaliEffectsViewSetGetOutputImage(void) -{ - ToolkitTestApplication application; - - EffectsView view = EffectsView::New(); - FrameBufferImage image = FrameBufferImage::New(); - DALI_TEST_CHECK( image ); - - view.SetOutputImage( image ); - DALI_TEST_CHECK( view.GetOutputImage() == image ); - - // Replace with another image - FrameBufferImage image2 = FrameBufferImage::New(); - DALI_TEST_CHECK( image2 ); - view.SetOutputImage( image2 ); - DALI_TEST_CHECK( view.GetOutputImage() == image2 ); - - // Remove output image - view.SetOutputImage( FrameBufferImage() ); - DALI_TEST_CHECK( ! view.GetOutputImage() ); - - END_TEST; -} - -int UtcDaliEffectsViewSetOutputImageN(void) -{ - ToolkitTestApplication application; - - EffectsView view; - try - { - view.SetOutputImage( FrameBufferImage::New() ); - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} - -int UtcDaliEffectsViewGetOutputImageN(void) +int UtcDaliEffectsViewSizeProperty(void) { ToolkitTestApplication application; - EffectsView view; - try - { - FrameBufferImage image = view.GetOutputImage(); - (void)image; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); -int UtcDaliEffectsViewGetEffectSizePropertyIndexP(void) -{ - ToolkitTestApplication application; + Property::Index idx = view.GetPropertyIndex( "effectSize" ); + DALI_TEST_EQUALS( idx, (Property::Index)EffectsView::Property::EFFECT_SIZE, TEST_LOCATION ); - EffectsView view = EffectsView::New(); - DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectSizePropertyIndex() ); + view.SetProperty( idx, 5 ); + Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_SIZE ); + int size; + DALI_TEST_CHECK( value.Get(size) ); + DALI_TEST_CHECK( size == 5 ); END_TEST; } -int UtcDaliEffectsViewGetEffectSizePropertyIndexN(void) +int UtcDaliEffectsViewOffsetProperty(void) { ToolkitTestApplication application; - EffectsView view; - try - { - Property::Index index = view.GetEffectSizePropertyIndex(); - (void)index; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} - -int UtcDaliEffectsViewGetEffectStrengthPropertyIndexP(void) -{ - ToolkitTestApplication application; - - EffectsView view = EffectsView::New(); - DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectStrengthPropertyIndex() ); - - END_TEST; -} - -int UtcDaliEffectsViewGetEffectStrengthPropertyIndexN(void) -{ - ToolkitTestApplication application; - - EffectsView view; - try - { - Property::Index index = view.GetEffectStrengthPropertyIndex(); - (void)index; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } - - END_TEST; -} - -int UtcDaliEffectsViewGetEffectOffsetPropertyIndexP(void) -{ - ToolkitTestApplication application; - - EffectsView view = EffectsView::New(); - DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectOffsetPropertyIndex() ); + EffectsView view = EffectsView::New( EffectsView::EMBOSS ); + Stage::GetCurrent().Add( view ); - END_TEST; -} + Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET ); + Vector3 offsetValue; + DALI_TEST_CHECK( value.Get(offsetValue) ); + DALI_TEST_EQUALS( offsetValue, Vector3::ZERO, TEST_LOCATION ); -int UtcDaliEffectsViewGetEffectOffsetPropertyIndexN(void) -{ - ToolkitTestApplication application; + Vector3 offsetSet( 2.f, 3.f, 4.f ); + view.SetProperty( EffectsView::Property::EFFECT_OFFSET, offsetSet); + application.SendNotification(); + application.Render(0); + value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET ); + value.Get(offsetValue); + DALI_TEST_EQUALS( offsetValue, offsetSet, TEST_LOCATION ); + + Vector3 offsetAnimate( 4.f, 6.f, 8.f ); + float durationSeconds(0.05f); + Animation animation = Animation::New( durationSeconds ); + animation.AnimateTo( Property(view,EffectsView::Property::EFFECT_OFFSET ), offsetAnimate ); + animation.Play(); + application.SendNotification(); + application.Render(static_cast(durationSeconds*1000.0f) + 1u/*just beyond the animation duration*/); - EffectsView view; - try - { - Property::Index index = view.GetEffectOffsetPropertyIndex(); - (void)index; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } + value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET ); + value.Get(offsetValue); + DALI_TEST_EQUALS( offsetValue, offsetAnimate, TEST_LOCATION ); END_TEST; } -int UtcDaliEffectsViewGetEffectColorPropertyIndexP(void) +int UtcDaliEffectsViewColorProperty(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); - DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectColorPropertyIndex() ); + EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW ); + Stage::GetCurrent().Add( view ); - END_TEST; -} + Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_COLOR ); + Vector4 colorValue; + DALI_TEST_CHECK( value.Get(colorValue) ); + DALI_TEST_EQUALS( colorValue, Color::WHITE, TEST_LOCATION ); -int UtcDaliEffectsViewGetEffectColorPropertyIndexN(void) -{ - ToolkitTestApplication application; + Vector4 colorSet( 0.2f, 0.3f, 0.4f, 0.5f ); + view.SetProperty( EffectsView::Property::EFFECT_COLOR, colorSet); + application.SendNotification(); + application.Render(0); + value = view.GetProperty( EffectsView::Property::EFFECT_COLOR ); + value.Get(colorValue); + DALI_TEST_EQUALS( colorValue, colorSet, TEST_LOCATION ); + + Vector4 colorAnimate( 0.5f, 0.6f, 0.8f, 1.f ); + float durationSeconds(0.05f); + Animation animation = Animation::New( durationSeconds ); + animation.AnimateTo( Property(view,EffectsView::Property::EFFECT_COLOR ), colorAnimate ); + animation.Play(); + application.SendNotification(); + application.Render(static_cast(durationSeconds*1000.0f) + 1u/*just beyond the animation duration*/); - EffectsView view; - try - { - Property::Index index = view.GetEffectColorPropertyIndex(); - (void)index; - DALI_TEST_CHECK( false ); // Should not get here - } - catch( ... ) - { - DALI_TEST_CHECK( true ); - } + value = view.GetProperty( EffectsView::Property::EFFECT_COLOR ); + value.Get(colorValue); + DALI_TEST_EQUALS( colorValue, colorAnimate, TEST_LOCATION ); END_TEST; } @@ -465,7 +341,7 @@ int UtcDaliEffectsViewGetSetBackgroundColor(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW); view.SetBackgroundColor( Color::RED ); DALI_TEST_CHECK( Color::RED == view.GetBackgroundColor() ); @@ -516,25 +392,22 @@ int UtcDaliEffectsViewSetRefreshOnDemandP(void) { ToolkitTestApplication application; - EffectsView view = EffectsView::New(); - FrameBufferImage image = FrameBufferImage::New(); - view.SetOutputImage( image ); - view.Enable(); + EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW); + view.SetSize(100.f, 100.f); Stage stage = Stage::GetCurrent(); stage.Add( view ); + application.SendNotification(); + application.Render(); RenderTaskList renderTaskList = stage.GetRenderTaskList(); DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS ); - DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS ); view.SetRefreshOnDemand( true ); DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ONCE ); - DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ONCE ); view.SetRefreshOnDemand( false ); DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS ); - DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS ); END_TEST; } @@ -563,23 +436,16 @@ int UtcDaliEffectsViewSizeSet(void) Stage stage = Stage::GetCurrent(); { - EffectsView view = EffectsView::New(); + EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW); view.SetSize( 200.0f, 200.0f, 0.0f ); stage.Add( view ); - view.Enable(); application.SendNotification(); application.Render(); - view.Disable(); - application.SendNotification(); - application.Render(); - DALI_TEST_EQUALS( view.GetCurrentSize(), Vector3( 200.0f, 200.0f, 0.0f ), TEST_LOCATION ); } { - EffectsView view = EffectsView::New(); - view.SetOutputImage( FrameBufferImage::New( 200, 200 ) ); - view.SetType( EffectsView::EMBOSS ); + EffectsView view = EffectsView::New(EffectsView::EMBOSS); view.SetSize( 200.0f, 200.0f, 0.0f ); stage.Add( view ); application.SendNotification(); @@ -589,8 +455,7 @@ int UtcDaliEffectsViewSizeSet(void) } { - EffectsView view = EffectsView::New(); - view.SetType( EffectsView::DROP_SHADOW ); + EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW); view.SetSize( 200.0f, 200.0f, 0.0f ); stage.Add( view ); application.SendNotification(); diff --git a/dali-toolkit/devel-api/controls/effects-view/effects-view.cpp b/dali-toolkit/devel-api/controls/effects-view/effects-view.cpp index d1757d7..2abab5a 100644 --- a/dali-toolkit/devel-api/controls/effects-view/effects-view.cpp +++ b/dali-toolkit/devel-api/controls/effects-view/effects-view.cpp @@ -27,9 +27,11 @@ namespace Dali namespace Toolkit { -EffectsView EffectsView::New() +EffectsView EffectsView::New( EffectType type ) { - return Internal::EffectsView::New(); + EffectsView effectsView = Internal::EffectsView::New(); + GetImpl(effectsView).SetType( type ); + return effectsView; } EffectsView::EffectsView() @@ -59,26 +61,11 @@ EffectsView::~EffectsView() { } -void EffectsView::SetType( EffectsView::EffectType type ) -{ - GetImpl(*this).SetType( type ); -} - EffectsView::EffectType EffectsView::GetType() const { return GetImpl(*this).GetType(); } -void EffectsView::Enable() -{ - GetImpl(*this).Enable(); -} - -void EffectsView::Disable() -{ - GetImpl(*this).Disable(); -} - void EffectsView::Refresh() { GetImpl(*this).Refresh(); @@ -94,36 +81,6 @@ void EffectsView::SetPixelFormat( Pixel::Format pixelFormat ) GetImpl(*this).SetPixelFormat( pixelFormat ); } -void EffectsView::SetOutputImage( FrameBufferImage image ) -{ - GetImpl(*this).SetOutputImage( image ); -} - -FrameBufferImage EffectsView::GetOutputImage() -{ - return GetImpl(*this).GetOutputImage(); -} - -Property::Index EffectsView::GetEffectSizePropertyIndex() const -{ - return GetImpl(*this).GetEffectSizePropertyIndex(); -} - -Property::Index EffectsView::GetEffectStrengthPropertyIndex() const -{ - return GetImpl(*this).GetEffectStrengthPropertyIndex(); -} - -Property::Index EffectsView::GetEffectOffsetPropertyIndex() const -{ - return GetImpl(*this).GetEffectOffsetPropertyIndex(); -} - -Property::Index EffectsView::GetEffectColorPropertyIndex() const -{ - return GetImpl(*this).GetEffectColorPropertyIndex(); -} - void EffectsView::SetBackgroundColor( const Vector4& color ) { GetImpl(*this).SetBackgroundColor(color); diff --git a/dali-toolkit/devel-api/controls/effects-view/effects-view.h b/dali-toolkit/devel-api/controls/effects-view/effects-view.h index 2255e1f..b734b41 100644 --- a/dali-toolkit/devel-api/controls/effects-view/effects-view.h +++ b/dali-toolkit/devel-api/controls/effects-view/effects-view.h @@ -42,7 +42,7 @@ class EffectsView; * * Example usage: Applying an emboss effect * ... - * EffectsView effectsView = EffectsView::New(); + * EffectsView effectsView = EffectsView::New( Toolkit::EffectsView::EMBOSS ); * * // set position and format * effectsView.SetParentOrigin( ParentOrigin::CENTER ); @@ -50,22 +50,15 @@ class EffectsView; * effectsView.SetPixelFormat( Pixel::RGBA8888 ); * * // set effect type and properties - * effectsView.SetType( Toolkit::EffectsView::EMBOSS ); * effectsView.SetProperty( effectsView.GetEffectSizePropertyIndex(), static_cast< float >( shadowSize ) ); * effectsView.SetProperty( effectsView.GetEffectOffsetPropertyIndex(), Vector3( shadowDistance.x, shadowDistance.y, 0.0f ) ); * effectsView.SetProperty( effectsView.GetEffectColorPropertyIndex(), shadowColor ); * - * // Render result to an offscreen - * effectsView.SetOutputImage( image ); - * * // Render once * effectsView.SetRefreshOnDemand( true ); * * // optionally set a clear color * effectsView.SetBackgroundColor( Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) ); - * - * // start effect processing - * effectsView.Enable(); */ class DALI_IMPORT_API EffectsView : public Control { @@ -78,12 +71,42 @@ public: INVALID_TYPE }; + /** + * @brief The start and end property ranges for this control. + */ + enum PropertyRange + { + PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, ///< @SINCE_1_0.0 + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices @SINCE_1_0.0 + + ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, ///< @SINCE_1_1.18 + ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000 ///< Reserve animatable property indices, @SINCE_1_1.18 + }; + + /** + * @brief An enumeration of properties belonging to the EffectsView class. + */ + struct Property + { + enum + { + // Event side properties + EFFECT_SIZE = PROPERTY_START_INDEX, ///< name "effectSize", type INTEGER + + // Animatable properties + EFFECT_OFFSET = ANIMATABLE_PROPERTY_START_INDEX, ///< name "effectOffset", type VECTOR3 + EFFECT_COLOR, ///< name "effectColor", type VECTOR4 + }; + }; + public: /** * Create an EffectsView object with default configuration + * @param[in] type The type of effect to be performed by the EffectView. + * A member of the EffectType enumeration. */ - static EffectsView New(); + static EffectsView New( EffectType type ); /** * Create an uninitialized EffectsView. Only derived versions can be instantiated. @@ -119,29 +142,12 @@ public: public: /** - * Set the effect type - * @param[in] type The type of effect to be performed by the EffectView. - * A member of the EffectType enumeration. - */ - void SetType( EffectType type ); - - /** * Get the effect type * @return The type of effect performed by the EffectView. A member of the EffectType enumeration. */ EffectType GetType() const; /** - * Enable the effect - */ - void Enable(); - - /** - * Disable the effect - */ - void Disable(); - - /** * Refresh/Redraw the effect */ void Refresh(); @@ -160,42 +166,6 @@ public: void SetPixelFormat( Pixel::Format pixelFormat ); /** - * Set the FrameBufferImage that will receive the final output of the EffectsView. - * @param[in] image User supplied FrameBufferImage that will receive the final output of the EffectsView. - */ - void SetOutputImage( FrameBufferImage image ); - - /** - * Get the FrameBufferImage that holds the final output of the EffectsView. - * @return The FrameBufferImage that holds the final output of the EffectsView. - */ - FrameBufferImage GetOutputImage(); - - /** - * Get the property index to the effect size - * @return The property index to the effect size - */ - Dali::Property::Index GetEffectSizePropertyIndex() const; - - /** - * Get the property index to the effect strength - * @return The property index to the effect strength - */ - Dali::Property::Index GetEffectStrengthPropertyIndex() const; - - /** - * Get the property index to the Vector3 specifying the effect offset (eg drop shadow offset) - * @return The property index to the Vector3 specifying the effect offset - */ - Dali::Property::Index GetEffectOffsetPropertyIndex() const; - - /** - * Get the property index to the effect color (eg shadow color) - * @return The property index to the effect color - */ - Dali::Property::Index GetEffectColorPropertyIndex() const; - - /** * Set background color for the view. The background will be filled with this color. * @param[in] color The background color. */ diff --git a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp index 28b64fa..d65b8fd 100644 --- a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp +++ b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp @@ -22,14 +22,16 @@ #include #include #include +#include #include #include #include // INTERNAL INCLUDES -#include "../../filters/blur-two-pass-filter.h" -#include "../../filters/emboss-filter.h" -#include "../../filters/spread-filter.h" +#include +#include +#include +#include namespace Dali { @@ -45,10 +47,13 @@ namespace Dali::BaseHandle Create() { - return Toolkit::EffectsView::New(); + return EffectsView::New(); } DALI_TYPE_REGISTRATION_BEGIN( Toolkit::EffectsView, Toolkit::Control, Create ) +DALI_PROPERTY_REGISTRATION( Toolkit, EffectsView, "effectSize", INTEGER, EFFECT_SIZE ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, EffectsView, "effectOffset", VECTOR3, EFFECT_OFFSET ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, EffectsView, "effectColor", Color::WHITE, EFFECT_COLOR ) DALI_TYPE_REGISTRATION_END() const Pixel::Format EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT = Pixel::RGBA8888; @@ -56,23 +61,36 @@ const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; const Vector4 EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR( 1.0f, 1.0f, 1.0f, 0.0 ); const bool EFFECTS_VIEW_REFRESH_ON_DEMAND(false); -// Custom properties -const char* const EFFECT_SIZE_PROPERTY_NAME = "EffectSize"; -const char* const EFFECT_STRENGTH_PROPERTY_NAME = "EffectStrength"; -const char* const EFFECT_OFFSET_PROPERTY_NAME = "EffectOffset"; -const char* const EFFECT_COLOR_PROPERTY_NAME = "EffectColor"; - -const float EFFECT_SIZE_DEFAULT( 1.0f ); -const float EFFECT_STRENGTH_DEFAULT( 0.5f ); -const Vector3 EFFECT_OFFSET_DEFAULT( 0.0f, 0.0f, 0.0f ); -const Vector4 EFFECT_COLOR_DEFAULT( Color::WHITE ); - -const char* const EFFECTS_VIEW_FRAGMENT_SOURCE = - "void main()\n" - "{\n" - " gl_FragColor = uColor;\n" - " gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n" - "}\n"; +const char* EFFECTS_VIEW_VERTEX_SOURCE = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + varying mediump vec2 vTexCoord;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform mediump vec3 effectOffset;\n + \n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vertexPosition.xyz *= uSize;\n + vertexPosition.xyz += effectOffset;\n + vertexPosition = uMvpMatrix * vertexPosition;\n + \n + vTexCoord = aPosition + vec2(0.5);\n + gl_Position = vertexPosition;\n + }\n +); + +const char* EFFECTS_VIEW_FRAGMENT_SOURCE = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 effectColor;\n + \n + void main()\n + {\n + gl_FragColor = effectColor;\n + gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n + }\n +); const float BLUR_KERNEL0[] = { 12.0f/16.0f, 2.0f/16.0f, 2.0f/16.0f }; @@ -113,17 +131,15 @@ Toolkit::EffectsView EffectsView::New() EffectsView::EffectsView() : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ), - mEffectType( Toolkit::EffectsView::INVALID_TYPE ), - mPixelFormat( EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT ), - mSpread(0.0f), + mChildrenRoot(Actor::New()), mBackgroundColor( EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR ), mTargetSize( Vector2::ZERO ), mLastSize( Vector2::ZERO ), - mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND), - mEffectSizePropertyIndex(Property::INVALID_INDEX), - mEffectStrengthPropertyIndex(Property::INVALID_INDEX), - mEffectOffsetPropertyIndex(Property::INVALID_INDEX), - mEffectColorPropertyIndex(Property::INVALID_INDEX) + mEffectSize(0), + mEffectType( Toolkit::EffectsView::INVALID_TYPE ), + mPixelFormat( EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT ), + mEnabled( false ), + mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND) { } @@ -136,24 +152,25 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type ) { if( mEffectType != type ) { - mEffectType = type; - RemoveFilters(); - switch( mEffectType ) + Actor self = Self(); + Property::Map rendererMap; + rendererMap.Insert( "rendererType", "image" ); + + switch( type ) { case Toolkit::EffectsView::DROP_SHADOW: { - mFilters.push_back( new SpreadFilter ); - mFilters.push_back( new BlurTwoPassFilter ); + mFilters.PushBack( new SpreadFilter ); + mFilters.PushBack( new BlurTwoPassFilter ); break; } case Toolkit::EffectsView::EMBOSS: { - mFilters.push_back( new SpreadFilter ); - mFilters.push_back( new EmbossFilter ); - mFilters.push_back( new BlurTwoPassFilter ); - mActorPostFilter.RemoveShaderEffect(); + mFilters.PushBack( new SpreadFilter ); + mFilters.PushBack( new EmbossFilter ); + mFilters.PushBack( new BlurTwoPassFilter ); break; } default: @@ -161,6 +178,14 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type ) break; } } + + Property::Map customShader; + customShader[ "vertexShader" ] = EFFECTS_VIEW_VERTEX_SOURCE; + customShader[ "fragmentShader" ] = EFFECTS_VIEW_FRAGMENT_SOURCE; + rendererMap[ "shader" ] = customShader; + Toolkit::RendererFactory::Get().ResetRenderer( mRendererPostFilter, self, rendererMap ); + + mEffectType = type; } } @@ -174,6 +199,7 @@ void EffectsView::Enable() // make sure resources are allocated and start the render tasks processing AllocateResources(); CreateRenderTasks(); + mEnabled = true; } void EffectsView::Disable() @@ -181,6 +207,7 @@ void EffectsView::Disable() // stop render tasks processing // Note: render target resources are automatically freed since we set the Image::Unused flag RemoveRenderTasks(); + mEnabled = false; } void EffectsView::Refresh() @@ -200,119 +227,48 @@ void EffectsView::SetPixelFormat( Pixel::Format pixelFormat ) mPixelFormat = pixelFormat; } -void EffectsView::SetOutputImage( FrameBufferImage image ) -{ - CustomActor self = Self(); - - if( mImageForResult != image ) - { - if( !image ) - { - if( mImageForResult ) - { - self.Remove( mActorForResult ); - mActorForResult.Reset(); - - self.Add( mActorPostFilter ); - self.Add( mActorForChildren ); - } - } - else - { - if( mImageForResult ) - { - self.Remove( mActorForResult ); - } - mActorForResult = Actor::New(); - mActorForResult.SetParentOrigin( ParentOrigin::CENTER ); - mActorForResult.SetSize( mTargetSize ); - mActorForResult.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - - Self().Add( mActorForResult ); - mActorForResult.Add( mActorPostFilter ); - mActorForResult.Add( mActorForChildren ); - } - mImageForResult = image; - } -} - -FrameBufferImage EffectsView::GetOutputImage() -{ - return mImageForResult; -} - -Property::Index EffectsView::GetEffectSizePropertyIndex() const -{ - return mEffectSizePropertyIndex; -} - -Property::Index EffectsView::GetEffectStrengthPropertyIndex() const -{ - return mEffectStrengthPropertyIndex; -} - -Property::Index EffectsView::GetEffectOffsetPropertyIndex() const +void EffectsView::SetBackgroundColor( const Vector4& color ) { - return mEffectOffsetPropertyIndex; + mBackgroundColor = color; } -Property::Index EffectsView::GetEffectColorPropertyIndex() const +Vector4 EffectsView::GetBackgroundColor() const { - return mEffectColorPropertyIndex; + return mBackgroundColor; } -void EffectsView::SetupProperties() +void EffectsView::SetEffectSize( int effectSize ) { - CustomActor self = Self(); + mEffectSize = effectSize; - // Register a property that the user can control the drop shadow offset - mEffectSizePropertyIndex = self.RegisterProperty(EFFECT_SIZE_PROPERTY_NAME, EFFECT_SIZE_DEFAULT, Property::READ_WRITE); - mEffectStrengthPropertyIndex = self.RegisterProperty(EFFECT_STRENGTH_PROPERTY_NAME, EFFECT_STRENGTH_DEFAULT, Property::READ_WRITE); - mEffectOffsetPropertyIndex = self.RegisterProperty(EFFECT_OFFSET_PROPERTY_NAME, EFFECT_OFFSET_DEFAULT); - mEffectColorPropertyIndex = self.RegisterProperty(EFFECT_COLOR_PROPERTY_NAME, EFFECT_COLOR_DEFAULT); - - Constraint positionConstraint = Constraint::New( mActorPostFilter, Actor::Property::POSITION, EqualToConstraint() ); - positionConstraint.AddSource( Source( self, mEffectOffsetPropertyIndex ) ); - positionConstraint.Apply(); + if( mEnabled ) + { + const size_t numFilters( mFilters.Size() ); + for( size_t i = 0; i < numFilters; ++i ) + { + mFilters[i]->Disable(); + } - Constraint colorConstraint = Constraint::New( mActorPostFilter, Actor::Property::COLOR, EqualToConstraint() ); - colorConstraint.AddSource( Source( self, mEffectColorPropertyIndex ) ); - colorConstraint.Apply(); -} + SetupFilters(); -void EffectsView::SetBackgroundColor( const Vector4& color ) -{ - mBackgroundColor = color; + for( size_t i = 0; i < numFilters; ++i ) + { + mFilters[i]->Enable(); + } + } } -Vector4 EffectsView::GetBackgroundColor() const +int EffectsView::GetEffectSize() { - return mBackgroundColor; + return mEffectSize; } // From Control void EffectsView::OnInitialize() { - ////////////////////////////////////////////////////// - // Create cameras - mCameraForChildren = CameraActor::New(); - mCameraForChildren.SetParentOrigin(ParentOrigin::CENTER); - - mActorForChildren = ImageActor::New(); - mActorForChildren.SetParentOrigin( ParentOrigin::CENTER ); - mActorForChildren.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - - mActorPostFilter = ImageActor::New(); - mActorPostFilter.SetParentOrigin( ParentOrigin::CENTER ); - mActorPostFilter.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - mActorPostFilter.SetShaderEffect( ShaderEffect::New( "", EFFECTS_VIEW_FRAGMENT_SOURCE ) ); - - // Connect to actor tree - Self().Add( mActorPostFilter ); - Self().Add( mActorForChildren ); - Self().Add( mCameraForChildren ); - - SetupProperties(); + CustomActor self = Self(); + mChildrenRoot.SetParentOrigin( ParentOrigin::CENTER ); + self.Add( mChildrenRoot ); } void EffectsView::OnSizeSet(const Vector3& targetSize) @@ -322,58 +278,77 @@ void EffectsView::OnSizeSet(const Vector3& targetSize) mTargetSize = Vector2(targetSize); // if we are already on stage, need to update render target sizes now to reflect the new size of this actor - if(Self().OnStage()) + if(mEnabled) { - AllocateResources(); + if( mLastSize != Vector2::ZERO ) + { + Disable(); + } + Enable(); } - if( mActorForResult ) + mChildrenRoot.SetSize( targetSize ); +} + +void EffectsView::OnStageConnection( int depth ) +{ + Control::OnStageConnection( depth ); + + Enable(); + + Actor self = Self(); + if( mRendererPostFilter ) { - mActorForResult.SetSize( targetSize ); + mRendererPostFilter.SetOnStage( self ); } - if( mActorForChildren ) + if( mRendererForChildren ) { - mActorForChildren.SetSize( targetSize ); + mRendererForChildren.SetOnStage( self ); } - if( mActorPostFilter ) +} + +void EffectsView::OnStageDisconnection() +{ + Disable(); + + const size_t numFilters( mFilters.Size() ); + for( size_t i = 0; i < numFilters; ++i ) { - mActorPostFilter.SetSize( targetSize ); + mFilters[i]->Disable(); } - // Children render camera must move when EffectsView object is resized. - // This is since we cannot change render target size - so we need to remap the child actors' rendering - // accordingly so they still exactly fill the render target. - // Note that this means the effective resolution of the child render changes as the EffectsView object - // changes size, this is the trade off for not being able to modify render target size - // Change camera z position based on EffectsView actor height - if( mCameraForChildren ) + Actor self = Self(); + if( mRendererPostFilter ) { - const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) ); - mCameraForChildren.SetZ( targetSize.height * cameraPosScale ); + mRendererPostFilter.SetOffStage( self ); } - - const size_t numFilters( mFilters.size() ); - for( size_t i = 0; i < numFilters; ++i ) + if( mRendererForChildren ) { - mFilters[i]->SetSize( mTargetSize ); + mRendererForChildren.SetOffStage( self ); } + Control::OnStageDisconnection(); } -void EffectsView::OnStageDisconnection() +void EffectsView::OnChildAdd( Actor& child ) { - const size_t numFilters( mFilters.size() ); - for( size_t i = 0; i < numFilters; ++i ) + Control::OnChildAdd( child ); + + if( child != mChildrenRoot && child != mCameraForChildren ) { - mFilters[i]->Disable(); + mChildrenRoot.Add( child ); } +} - Control::OnStageDisconnection(); +void EffectsView::OnChildRemove( Actor& child ) +{ + mChildrenRoot.Remove( child ); + + Control::OnChildRemove( child ); } void EffectsView::SetupFilters() { - int effectSize = static_cast< int >( Self().GetProperty( mEffectSizePropertyIndex ).Get() ); switch( mEffectType ) { case Toolkit::EffectsView::DROP_SHADOW: @@ -381,23 +356,23 @@ void EffectsView::SetupFilters() SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] ); spreadFilter->SetInputImage( mImageForChildren ); spreadFilter->SetOutputImage( mImagePostFilter ); - spreadFilter->SetRootActor( Self() ); + spreadFilter->SetRootActor( mChildrenRoot ); spreadFilter->SetBackgroundColor( mBackgroundColor ); spreadFilter->SetPixelFormat( mPixelFormat ); spreadFilter->SetSize( mTargetSize ); - spreadFilter->SetSpread( effectSize ); + spreadFilter->SetSpread( mEffectSize ); BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[1] ); blurFilter->SetInputImage( mImagePostFilter ); blurFilter->SetOutputImage( mImagePostFilter ); - blurFilter->SetRootActor( Self() ); + blurFilter->SetRootActor( mChildrenRoot ); blurFilter->SetBackgroundColor( mBackgroundColor ); blurFilter->SetPixelFormat( mPixelFormat ); blurFilter->SetSize( mTargetSize ); const float* kernel(NULL); size_t kernelSize(0); - switch( effectSize ) + switch( mEffectSize ) { case 4: { kernel = BLUR_KERNEL4; kernelSize = sizeof(BLUR_KERNEL4)/sizeof(BLUR_KERNEL4[0]); break; } case 3: { kernel = BLUR_KERNEL3; kernelSize = sizeof(BLUR_KERNEL3)/sizeof(BLUR_KERNEL3[0]); break; } @@ -414,16 +389,16 @@ void EffectsView::SetupFilters() SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] ); spreadFilter->SetInputImage( mImageForChildren ); spreadFilter->SetOutputImage( mImagePostFilter ); - spreadFilter->SetRootActor( Self() ); + spreadFilter->SetRootActor( mChildrenRoot ); spreadFilter->SetBackgroundColor( mBackgroundColor ); spreadFilter->SetPixelFormat( Pixel::RGBA8888 ); spreadFilter->SetSize( mTargetSize ); - spreadFilter->SetSpread( effectSize ); + spreadFilter->SetSpread( mEffectSize ); EmbossFilter* embossFilter = static_cast< EmbossFilter* >( mFilters[1] ); embossFilter->SetInputImage( mImagePostFilter ); embossFilter->SetOutputImage( mImagePostFilter ); - embossFilter->SetRootActor( Self() ); + embossFilter->SetRootActor( mChildrenRoot ); embossFilter->SetBackgroundColor( mBackgroundColor ); embossFilter->SetPixelFormat( Pixel::RGBA8888 ); embossFilter->SetSize( mTargetSize ); @@ -431,7 +406,7 @@ void EffectsView::SetupFilters() BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[2] ); blurFilter->SetInputImage( mImagePostFilter ); blurFilter->SetOutputImage( mImagePostFilter ); - blurFilter->SetRootActor( Self() ); + blurFilter->SetRootActor( mChildrenRoot ); blurFilter->SetBackgroundColor( Vector4( 0.5f, 0.5f, 0.5f, 0.0 ) ); blurFilter->SetPixelFormat( Pixel::RGBA8888 ); blurFilter->SetSize( mTargetSize ); @@ -450,14 +425,18 @@ void EffectsView::AllocateResources() if(mTargetSize != mLastSize) { mLastSize = mTargetSize; - SetupCameras(); + Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + Actor self = Self(); + mImageForChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED ); - mActorForChildren.SetImage(mImageForChildren); + rendererFactory.ResetRenderer(mRendererForChildren, self, mImageForChildren); + mRendererForChildren.SetDepthIndex( DepthIndex::CONTENT+1 ); mImagePostFilter = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED ); - mActorPostFilter.SetImage(mImagePostFilter); + rendererFactory.ResetRenderer(mRendererPostFilter, self, mImagePostFilter); + mRendererPostFilter.SetDepthIndex( DepthIndex::CONTENT ); SetupFilters(); } @@ -465,26 +444,39 @@ void EffectsView::AllocateResources() void EffectsView::SetupCameras() { - const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) ); - - // Create and place a camera for the children render, corresponding to its render target size - mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - // TODO: how do we pick a reasonable value for near clip? Needs to relate to normal camera the user renders with, but we don't have a handle on it - mCameraForChildren.SetNearClippingPlane(1.0f); - mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height); - mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor - mCameraForChildren.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosScale); - mCameraForChildren.SetZ( mTargetSize.height * cameraPosScale ); + if( !mCameraForChildren ) + { + // Create a camera for the children render, corresponding to its render target size + mCameraForChildren = CameraActor::New(mTargetSize); + mCameraForChildren.SetParentOrigin(ParentOrigin::CENTER); + mCameraForChildren.SetInvertYAxis( true ); + Self().Add( mCameraForChildren ); + } + else + { + // place the camera for the children render, corresponding to its render target size + const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) ); + mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); + mCameraForChildren.SetNearClippingPlane(1.0f); + mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height); + mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor + mCameraForChildren.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosScale); + mCameraForChildren.SetZ( mTargetSize.height * cameraPosScale ); + } } void EffectsView::CreateRenderTasks() { + if( mTargetSize == Vector2::ZERO ) + { + return; + } RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); // create render task to render our child actors to offscreen buffer mRenderTaskForChildren = taskList.CreateTask(); mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS ); - mRenderTaskForChildren.SetSourceActor( Self() ); + mRenderTaskForChildren.SetSourceActor( mChildrenRoot ); mRenderTaskForChildren.SetExclusive(true); mRenderTaskForChildren.SetInputEnabled( false ); mRenderTaskForChildren.SetClearColor( mBackgroundColor ); @@ -493,35 +485,25 @@ void EffectsView::CreateRenderTasks() mRenderTaskForChildren.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly // Enable image filters - const size_t numFilters( mFilters.size() ); + const size_t numFilters( mFilters.Size() ); for( size_t i = 0; i < numFilters; ++i ) { mFilters[i]->Enable(); } - - // create render task to render result of the image filters to the final offscreen - if( mImageForResult ) - { - mRenderTaskForResult = taskList.CreateTask(); - mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS ); - mRenderTaskForResult.SetSourceActor( mActorForResult ); - mRenderTaskForResult.SetExclusive(true); - mRenderTaskForResult.SetInputEnabled( false ); - mRenderTaskForResult.SetClearColor( mBackgroundColor ); - mRenderTaskForResult.SetClearEnabled( true ); - mRenderTaskForResult.SetTargetFrameBuffer( mImageForResult ); - mRenderTaskForResult.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly - } } void EffectsView::RemoveRenderTasks() { + if( mTargetSize == Vector2::ZERO ) + { + return; + } + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); taskList.RemoveTask(mRenderTaskForChildren); - taskList.RemoveTask(mRenderTaskForResult); - const size_t numFilters( mFilters.size() ); + const size_t numFilters( mFilters.Size() ); for( size_t i = 0; i < numFilters; ++i ) { mFilters[i]->Disable(); @@ -537,12 +519,7 @@ void EffectsView::RefreshRenderTasks() mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS ); } - if( mRenderTaskForResult ) - { - mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS ); - } - - const size_t numFilters( mFilters.size() ); + const size_t numFilters( mFilters.Size() ); for( size_t i = 0; i < numFilters; ++i ) { mFilters[i]->Refresh(); @@ -551,12 +528,63 @@ void EffectsView::RefreshRenderTasks() void EffectsView::RemoveFilters() { - const size_t numFilters( mFilters.size() ); + const size_t numFilters( mFilters.Size() ); for( size_t i = 0; i < numFilters; ++i ) { delete mFilters[i]; } - mFilters.clear(); + mFilters.Release(); +} + +void EffectsView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +{ + Toolkit::EffectsView effectsView = Toolkit::EffectsView::DownCast( Dali::BaseHandle( object ) ); + + if ( effectsView ) + { + switch ( index ) + { + case Toolkit::EffectsView::Property::EFFECT_SIZE: + { + int effectSize; + if( value.Get( effectSize ) ) + { + GetImpl( effectsView ).SetEffectSize( effectSize ); + } + break; + } + default: + { + break; + } + } + } +} + +Property::Value EffectsView::GetProperty( BaseObject* object, Property::Index propertyIndex ) +{ + Property::Value value; + + Toolkit::EffectsView imageview = Toolkit::EffectsView::DownCast( Dali::BaseHandle( object ) ); + + if ( imageview ) + { + EffectsView& impl = GetImpl( imageview ); + switch ( propertyIndex ) + { + case Toolkit::EffectsView::Property::EFFECT_SIZE: + { + value = impl.GetEffectSize(); + break; + } + default: + { + break; + } + } + } + + return value; } } // namespace Internal diff --git a/dali-toolkit/internal/controls/effects-view/effects-view-impl.h b/dali-toolkit/internal/controls/effects-view/effects-view-impl.h index a39a1f7..bf6569d 100644 --- a/dali-toolkit/internal/controls/effects-view/effects-view-impl.h +++ b/dali-toolkit/internal/controls/effects-view/effects-view-impl.h @@ -20,15 +20,14 @@ // EXTERNAL INCLUDES #include -#include #include #include -#include // INTERNAL INCLUDES -#include #include +#include #include +#include namespace Dali { @@ -80,12 +79,6 @@ public: /// @copydoc Dali::Toolkit::EffectsView::GetType Toolkit::EffectsView::EffectType GetType() const; - /// @copydoc Dali::Toolkit::EffectsView::Enable - void Enable(); - - /// @copydoc Dali::Toolkit::EffectsView::Disable - void Disable(); - /// @copydoc Dali::Toolkit::EffectsView::Refresh void Refresh(); @@ -95,40 +88,46 @@ public: /// @copydoc Dali::Toolkit::EffectsView::SetPixelFormat void SetPixelFormat( Pixel::Format pixelFormat ); - /// @copydoc Dali::Toolkit::EffectsView::SetOutputImage - void SetOutputImage( FrameBufferImage image ); - - /// @copydoc Dali::Toolkit::EffectsView::GetOutputImage - FrameBufferImage GetOutputImage(); - - /// @copydoc Dali::Toolkit::EffectsView::GetEffectSizePropertyIndex - Property::Index GetEffectSizePropertyIndex() const; - - /// @copydoc Dali::Toolkit::EffectsView::GetEffectStrengthPropertyIndex - Property::Index GetEffectStrengthPropertyIndex() const; - - /// @copydoc Dali::Toolkit::EffectsView::GetEffectOffsetPropertyIndex - Property::Index GetEffectOffsetPropertyIndex() const; - - /// @copydoc Dali::Toolkit::EffectsView::GetEffectColorPropertyIndex - Property::Index GetEffectColorPropertyIndex() const; - /// @copydoc Dali::Toolkit::EffectsView::SetBackgroundColor(const Vector4&) void SetBackgroundColor( const Vector4& color ); /// @copydoc Dali::Toolkit::GaussianBlurView::GetBackgroundColor Vector4 GetBackgroundColor() const; -private: /** - * Register and setup indices for EffectsView properties + * Set the effect size which decides the size of filter kernel. + * @param[in] effectSize The effect size. + */ + void SetEffectSize( int effectSize ); + + /** + * Get the effect size. + * @return The effect size. + */ + int GetEffectSize(); + + // Properties + /** + * Called when a property of an object of this type is set. + * @param[in] object The object whose property is set. + * @param[in] index The property index. + * @param[in] value The new property value. + */ + static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ); + + + /** + * Called to retrieve a property of an object of this type. + * @param[in] object The object whose property is to be retrieved. + * @param[in] index The property index. + * @return The current value of the property. */ - void SetupProperties(); + static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex ); private: // From Control /** - * @copydoc Toolkit::Control::OnInitialize() + * @copydoc Toolkit::Internal::Control::OnInitialize() */ virtual void OnInitialize(); @@ -137,12 +136,37 @@ private: // From Control */ virtual void OnSizeSet( const Vector3& targetSize ); + /** + * @copydoc Toolkit::Internal::Control::OnStageConnection + */ + virtual void OnStageConnection( int depth ); + + /** + * @copydoc Toolkit::Internal::Control::OnStageDisconnection + */ + virtual void OnStageDisconnection(); + + /** + * @copydoc Toolkit::Internal::Control::OnChildAdd + */ + virtual void OnChildAdd( Actor& child ); + + /** + * @copydoc Toolkit::Internal::Control::OnChildRemove + */ + virtual void OnChildRemove( Actor& child ); + private: /** - * Callback received when the control is disconnected from the stage. + * Enable the effect when the control is set on stage */ - void OnStageDisconnection(); + void Enable(); + + /** + * Disable the effect when the control is set off stage + */ + void Disable(); /** * Setup image filters @@ -188,21 +212,14 @@ private: EffectsView& operator = ( const EffectsView& ); private: // attributes/properties - Toolkit::EffectsView::EffectType mEffectType; ///////////////////////////////////////////////////////////// // for rendering all user added children to offscreen target FrameBufferImage mImageForChildren; - ImageActor mActorForChildren; + Toolkit::ControlRenderer mRendererForChildren; RenderTask mRenderTaskForChildren; CameraActor mCameraForChildren; - - ///////////////////////////////////////////////////////////// - Pixel::Format mPixelFormat; ///< pixel format used by render targets - - ///////////////////////////////////////////////////////////// - // downsampling is used for the separated blur passes to get increased blur with the same number of samples and also to make rendering quicker - float mSpread; + Actor mChildrenRoot; // for creating a subtree for all user added child actors ///////////////////////////////////////////////////////////// // background fill color @@ -212,40 +229,23 @@ private: // attributes/properties // for checking if we need to reallocate render targets Vector2 mTargetSize; Vector2 mLastSize; - - bool mRefreshOnDemand; - - ///////////////////////////////////////////////////////////// - // horizontal spread objects - FrameBufferImage mImageForHorzSpread; - ImageActor mActorForHorzSpread; - RenderTask mRenderTaskForHorzSpread; - - ///////////////////////////////////////////////////////////// - // vertical spread objects - FrameBufferImage mImageForVertSpread; - ImageActor mActorForVertSpread; - RenderTask mRenderTaskForVertSpread; - - CameraActor mCameraForSpread; - ///////////////////////////////////////////////////////////// // post blur image FrameBufferImage mImagePostFilter; - ImageActor mActorPostFilter; + Toolkit::ControlRenderer mRendererPostFilter; + + Vector mFilters; ///////////////////////////////////////////////////////////// - // final image - FrameBufferImage mImageForResult; - Actor mActorForResult; - RenderTask mRenderTaskForResult; + // downsampling is used for the separated blur passes to get increased blur with the same number of samples and also to make rendering quicker + int mEffectSize; - Property::Index mEffectSizePropertyIndex; - Property::Index mEffectStrengthPropertyIndex; - Property::Index mEffectOffsetPropertyIndex; - Property::Index mEffectColorPropertyIndex; + ///////////////////////////////////////////////////////////// + Toolkit::EffectsView::EffectType mEffectType; + Pixel::Format mPixelFormat; ///< pixel format used by render targets - std::vector mFilters; + bool mEnabled:1; + bool mRefreshOnDemand:1; }; // class EffectsView } // namespace Internal diff --git a/dali-toolkit/internal/filters/blur-two-pass-filter.cpp b/dali-toolkit/internal/filters/blur-two-pass-filter.cpp index af62fb3..1b3a5f1 100644 --- a/dali-toolkit/internal/filters/blur-two-pass-filter.cpp +++ b/dali-toolkit/internal/filters/blur-two-pass-filter.cpp @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include // INTERNAL INCLUDES @@ -55,36 +57,20 @@ const float DEFAULT_KERNEL4[] = { 2.0f/16.0f, 1.5f/16.0f, 1.5f/16.0f, 1.5f/16.0f 1.0f/16.0f, 1.0f/16.0f, 1.0f/16.0f, 0.5f/16.0f, 0.5f/16.0f, 0.5f/16.0f, 0.5f/16.0f }; - -const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; - const char* BLUR_TWO_PASS_FRAGMENT_SOURCE = { "precision highp float;\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" "uniform vec2 uSampleOffsets[NUM_SAMPLES];\n" "uniform float uSampleWeights[NUM_SAMPLES];\n" "void main()\n" "{\n" " vec4 color = vec4(0.0);\n" - "# ifdef DEBUG_RENDER\n" - " if( vTexCoord.s < 0.495 )\n" - " {\n" - "# endif //def DEBUG_RENDER\n" - " for( int i = 0; i < NUM_SAMPLES; ++i )\n" - " {\n" - " color += texture2D( sTexture, vTexCoord + uSampleOffsets[i] ) * uSampleWeights[i];\n" - " }\n" - "# ifdef DEBUG_RENDER\n" - " }\n" - " else if( vTexCoord.s > 0.505 )\n" - " {\n" - " color = texture2D( sTexture, vTexCoord );\n" - " }\n" - " else\n" + " for( int i = 0; i < NUM_SAMPLES; ++i )\n" " {\n" - " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" + " color += texture2D( sTexture, vTexCoord + uSampleOffsets[i] ) * uSampleWeights[i];\n" " }\n" - "# endif //def DEBUG_RENDER\n" " gl_FragColor = color;\n" "}\n" }; @@ -106,7 +92,10 @@ std::string GetWeightUniformName( int index ) const char* BLEND_TWO_IMAGES_FRAGMENT_SOURCE = { "precision highp float;\n" - "uniform float uBlurStrength; \n " + "uniform float uBlurStrength;\n " + "uniform sampler2D sTexture;\n" + "uniform sampler2D sEffect;\n" + "varying mediump vec2 vTexCoord;\n" "void main()\n" "{\n" " gl_FragColor = texture2D( sTexture, vTexCoord ) * uBlurStrength" @@ -114,10 +103,8 @@ const char* BLEND_TWO_IMAGES_FRAGMENT_SOURCE = "}\n" }; -std::string GetBlurStrengthUniformName() -{ - return "uBlurStrength"; -} +const char* const BLUR_STRENGTH_UNIFORM_NAME( "uBlurStrength" ); +const char* const EFFECT_IMAGE_NAME( "sEffect" ); } // namespace @@ -125,9 +112,10 @@ std::string GetBlurStrengthUniformName() BlurTwoPassFilter::BlurTwoPassFilter() : ImageFilter() { - mShaderForBlending = ShaderEffect::New( "", BLEND_TWO_IMAGES_FRAGMENT_SOURCE ); - mShaderForBlending.SetUniform( GetBlurStrengthUniformName(), 1.f ); - mBlurStrengthPropertyIndex = mShaderForBlending.GetPropertyIndex( GetBlurStrengthUniformName() ); + // create blending actor and register the property in constructor + // to make sure that GetBlurStrengthPropertyIndex() always returns a valid index + mActorForBlending = Toolkit::ImageView::New(); + mBlurStrengthPropertyIndex = mActorForBlending.RegisterProperty( BLUR_STRENGTH_UNIFORM_NAME, 1.f ); } BlurTwoPassFilter::~BlurTwoPassFilter() @@ -136,37 +124,24 @@ BlurTwoPassFilter::~BlurTwoPassFilter() void BlurTwoPassFilter::Enable() { - mCameraForBlur = CameraActor::New(); - mCameraForBlur.SetParentOrigin(ParentOrigin::CENTER); - // create actor to render input with applied emboss effect - mActorForInput = ImageActor::New( mInputImage ); + mActorForInput = Toolkit::ImageView::New( mInputImage ); mActorForInput.SetParentOrigin( ParentOrigin::CENTER ); mActorForInput.SetSize( mTargetSize ); - mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // create internal offscreen for result of horizontal pass mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED ); - // create an actor to render mImageForHorz for vertical blur pass - mActorForHorz = ImageActor::New( mImageForHorz ); + mActorForHorz = Toolkit::ImageView::New( mImageForHorz ); mActorForHorz.SetParentOrigin( ParentOrigin::CENTER ); mActorForHorz.SetSize( mTargetSize ); - mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // create internal offscreen for result of the two pass blurred image mBlurredImage = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED); - // create an actor to blend the blurred image and the input image with the given blur strength - mActorForBlending = ImageActor::New( mBlurredImage ); + mActorForBlending.SetImage( mBlurredImage ); mActorForBlending.SetParentOrigin( ParentOrigin::CENTER ); mActorForBlending.SetSize( mTargetSize ); - mActorForBlending.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - - mRootActor.Add( mActorForInput ); - mRootActor.Add( mActorForHorz ); - mRootActor.Add( mActorForBlending ); - mRootActor.Add( mCameraForBlur ); // create custom shader effect if( !GetKernelSize() ) @@ -175,32 +150,50 @@ void BlurTwoPassFilter::Enable() } int kernelSize( static_cast< int >(GetKernelSize()) ); - std::ostringstream fragmentSource; - if( mDebugRender ) - { - fragmentSource << "#define DEBUG_RENDER\n"; - } - fragmentSource << "#define NUM_SAMPLES " << kernelSize << "\n"; - fragmentSource << BLUR_TWO_PASS_FRAGMENT_SOURCE; - mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() ); - mActorForInput.SetShaderEffect( mShaderForHorz ); - mShaderForVert = ShaderEffect::New( "", fragmentSource.str() ); - mActorForHorz.SetShaderEffect( mShaderForVert ); - for( int i = 0; i < kernelSize; ++i ) { const std::string offsetUniform( GetOffsetUniformName( i ) ); const std::string weightUniform( GetWeightUniformName( i ) ); - mShaderForHorz.SetUniform( offsetUniform, Vector2(mKernel[i]) * Vector2::XAXIS ); - mShaderForHorz.SetUniform( weightUniform, mKernel[i].z ); + mActorForInput.RegisterProperty( offsetUniform, Vector2(mKernel[i]) * Vector2::XAXIS ); + mActorForInput.RegisterProperty( weightUniform, mKernel[i].z ); - mShaderForVert.SetUniform( offsetUniform, Vector2(mKernel[i]) * Vector2::YAXIS ); - mShaderForVert.SetUniform( weightUniform, mKernel[i].z ); + mActorForHorz.RegisterProperty( offsetUniform, Vector2(mKernel[i]) * Vector2::YAXIS ); + mActorForHorz.RegisterProperty( weightUniform, mKernel[i].z ); } - mActorForBlending.SetShaderEffect( mShaderForBlending ); - mShaderForBlending.SetEffectImage( mInputImage ); + // Set up blur-two-pass custom shader + std::ostringstream fragmentSource; + fragmentSource << "#define NUM_SAMPLES " << kernelSize << "\n"; + fragmentSource << BLUR_TWO_PASS_FRAGMENT_SOURCE; + + Property::Map customShader; + customShader[ "fragmentShader" ] = fragmentSource.str(); + Property::Map rendererMap; + rendererMap.Insert( "shader", customShader ); + mActorForInput.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + mActorForHorz.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + + // Set up blend-two-image custom shader + customShader[ "fragmentShader" ] = BLEND_TWO_IMAGES_FRAGMENT_SOURCE; + rendererMap[ "shader"] = customShader; + mActorForBlending.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + + mRootActor.Add( mActorForInput ); + mRootActor.Add( mActorForHorz ); + mRootActor.Add( mActorForBlending ); + + // Add effect texture to blend-two-image custom shader + Material material = mActorForBlending.GetRendererAt(0).GetMaterial(); + int textureIndex = material.GetTextureIndex( EFFECT_IMAGE_NAME ); + if( textureIndex == -1 ) + { + material.AddTexture( mInputImage, EFFECT_IMAGE_NAME ); + } + else + { + material.SetTextureImage( textureIndex, mInputImage ); + } SetupCamera(); CreateRenderTasks(); @@ -210,10 +203,10 @@ void BlurTwoPassFilter::Disable() { if( mRootActor ) { - if( mCameraForBlur ) + if( mCameraActor ) { - mRootActor.Remove( mCameraForBlur ); - mCameraForBlur.Reset(); + mRootActor.Remove( mCameraActor ); + mCameraActor.Reset(); } if( mActorForInput ) @@ -228,12 +221,6 @@ void BlurTwoPassFilter::Disable() mActorForHorz.Reset(); } - if( mActorForBlending ) - { - mRootActor.Remove( mActorForBlending ); - mActorForBlending.Reset(); - } - RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); if( mRenderTaskForHorz ) @@ -290,17 +277,7 @@ void BlurTwoPassFilter::SetSize( const Vector2& size ) Handle BlurTwoPassFilter::GetHandleForAnimateBlurStrength() { - return mShaderForBlending; -} - -void BlurTwoPassFilter::SetupCamera() -{ - // Create and place a camera for the embossing render, corresponding to its render target size - mCameraForBlur.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - mCameraForBlur.SetNearClippingPlane(1.0f); - mCameraForBlur.SetAspectRatio(mTargetSize.width / mTargetSize.height); - mCameraForBlur.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor - mCameraForBlur.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f))); + return mActorForBlending; } void BlurTwoPassFilter::CreateRenderTasks() @@ -316,7 +293,7 @@ void BlurTwoPassFilter::CreateRenderTasks() mRenderTaskForHorz.SetClearEnabled( true ); mRenderTaskForHorz.SetClearColor( mBackgroundColor ); mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz ); - mRenderTaskForHorz.SetCameraActor( mCameraForBlur ); + mRenderTaskForHorz.SetCameraActor( mCameraActor ); // use the internal buffer and perform a horizontal blur targeting the output buffer mRenderTaskForVert = taskList.CreateTask(); @@ -327,7 +304,7 @@ void BlurTwoPassFilter::CreateRenderTasks() mRenderTaskForVert.SetClearEnabled( true ); mRenderTaskForVert.SetClearColor( mBackgroundColor ); mRenderTaskForVert.SetTargetFrameBuffer( mBlurredImage ); - mRenderTaskForVert.SetCameraActor( mCameraForBlur ); + mRenderTaskForVert.SetCameraActor( mCameraActor ); //Perform a blending between the blurred image and the input image mRenderTaskForBlending = taskList.CreateTask(); @@ -338,7 +315,7 @@ void BlurTwoPassFilter::CreateRenderTasks() mRenderTaskForBlending.SetClearEnabled( true ); mRenderTaskForBlending.SetClearColor( mBackgroundColor ); mRenderTaskForBlending.SetTargetFrameBuffer( mOutputImage ); - mRenderTaskForBlending.SetCameraActor( mCameraForBlur ); + mRenderTaskForBlending.SetCameraActor( mCameraActor ); } } // namespace Internal diff --git a/dali-toolkit/internal/filters/blur-two-pass-filter.h b/dali-toolkit/internal/filters/blur-two-pass-filter.h index 1e723b9..e130897 100644 --- a/dali-toolkit/internal/filters/blur-two-pass-filter.h +++ b/dali-toolkit/internal/filters/blur-two-pass-filter.h @@ -19,10 +19,9 @@ */ // EXTERNAL INCLUDES -#include -#include #include -#include +#include +#include // INTERNAL INCLUDES #include "image-filter.h" @@ -79,10 +78,6 @@ public: // From ImageFilter Handle GetHandleForAnimateBlurStrength(); private: - /** - * Setup position and parameters for camera - */ - void SetupCamera(); /** * Setup render tasks for blur @@ -95,26 +90,21 @@ private: private: // Attributes - CameraActor mCameraForBlur; - // To perform horizontal blur from mInputImage to mImageForHorz - RenderTask mRenderTaskForHorz; - ImageActor mActorForInput; - FrameBufferImage mImageForHorz; - ShaderEffect mShaderForHorz; + RenderTask mRenderTaskForHorz; + Toolkit::ImageView mActorForInput; + FrameBufferImage mImageForHorz; // To perform vertical blur from mImageForHorz to mOutputImage - RenderTask mRenderTaskForVert; - ImageActor mActorForHorz; - ShaderEffect mShaderForVert; - FrameBufferImage mBlurredImage; + RenderTask mRenderTaskForVert; + Toolkit::ImageView mActorForHorz; + FrameBufferImage mBlurredImage; // To blend the blurred image and input image according to the blur strength - RenderTask mRenderTaskForBlending; - ImageActor mActorForBlending; - Actor mRootActorForBlending; - ShaderEffect mShaderForBlending; - Property::Index mBlurStrengthPropertyIndex; + RenderTask mRenderTaskForBlending; + Toolkit::ImageView mActorForBlending; + Actor mRootActorForBlending; + Property::Index mBlurStrengthPropertyIndex; }; // class BlurTwoPassFilter diff --git a/dali-toolkit/internal/filters/emboss-filter.cpp b/dali-toolkit/internal/filters/emboss-filter.cpp index f437c73..e44877e 100644 --- a/dali-toolkit/internal/filters/emboss-filter.cpp +++ b/dali-toolkit/internal/filters/emboss-filter.cpp @@ -22,8 +22,10 @@ #include #include #include +#include #include -#include +#include +#include // INTERNAL INCLUDES @@ -39,74 +41,38 @@ namespace Internal namespace { -const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; - -const char* EMBOSS_FRAGMENT_SOURCE1 = +const char* EMBOSS_FRAGMENT_SOURCE = { "precision highp float;\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" "uniform vec2 uTexScale;\n" + "uniform vec3 uCoefficient;\n" "\n" "void main()\n" "{\n" - " vec4 color;\n" - "# ifdef DEBUG_RENDER\n" - " if( vTexCoord.s < 0.495 )\n" - " {\n" - "# endif //def DEBUG_RENDER\n" - " color = 2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n" - " color += -1.0 * texture2D( sTexture, vTexCoord );\n" - " color += -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n" - "# ifdef DEBUG_RENDER\n" - " }\n" - " else if( vTexCoord.s > 0.505 )\n" - " {\n" - " color = texture2D( sTexture, vTexCoord );\n" - " }\n" - " else\n" - " {\n" - " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" - " }\n" - "# endif //def DEBUG_RENDER\n" - " gl_FragColor = uColor * color;\n" + " vec4 color = uCoefficient.x * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n" + " color += uCoefficient.y * texture2D( sTexture, vTexCoord );\n" + " color += uCoefficient.z * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n" + " gl_FragColor = color;\n" "}\n" }; -const char* EMBOSS_FRAGMENT_SOURCE2 = +const char* const COMPOSITE_FRAGMENT_SOURCE = { - "precision highp float;\n" - "uniform vec2 uTexScale;\n" - "\n" - "void main()\n" - "{\n" - " vec4 color;\n" - "# ifdef DEBUG_RENDER\n" - " if( vTexCoord.s < 0.495 )\n" - " {\n" - "# endif //def DEBUG_RENDER\n" - " color = -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n" - " color += -1.0 * texture2D( sTexture, vTexCoord );\n" - " color += 2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n" - "# ifdef DEBUG_RENDER\n" - " }\n" - " else if( vTexCoord.s > 0.505 )\n" - " {\n" - " color = texture2D( sTexture, vTexCoord );\n" - " }\n" - " else\n" - " {\n" - " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" - " }\n" - "# endif //def DEBUG_RENDER\n" - " gl_FragColor = uColor * color;\n" - "}\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" + "uniform lowp vec4 uEffectColor;\n" + "void main()\n" + "{\n" + " gl_FragColor = uEffectColor;\n" + " gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n" + "}\n" }; -const char* const COMPOSITE_FRAGMENT_SOURCE = - "void main()\n" - "{\n" - " gl_FragColor = uColor;\n" - " gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n" - "}\n"; +const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" ); +const char* const COEFFICIENT_UNIFORM_NAME( "uCoefficient" ); +const char* const COLOR_UNIFORM_NAME( "uEffectColor" ); } // namespace @@ -121,73 +87,56 @@ EmbossFilter::~EmbossFilter() void EmbossFilter::Enable() { - // Create camera - mCameraActor = CameraActor::New(); - mCameraActor.SetParentOrigin(ParentOrigin::CENTER); - mImageForEmboss1 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED ); mImageForEmboss2 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED ); + Property::Map customShader; + customShader[ "fragmentShader" ] = EMBOSS_FRAGMENT_SOURCE; + Property::Map rendererMap; + rendererMap.Insert( "shader", customShader ); + // create actor to render input with applied emboss effect - mActorForInput1 = ImageActor::New( mInputImage ); + mActorForInput1 = Toolkit::ImageView::New( mInputImage ); mActorForInput1.SetParentOrigin( ParentOrigin::CENTER ); mActorForInput1.SetSize(mTargetSize); - mActorForInput1.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - mActorForInput1.SetColor( Color::WHITE ); + Vector2 textureScale( 1.5f/mTargetSize.width, 1.5f/mTargetSize.height); + mActorForInput1.RegisterProperty( TEX_SCALE_UNIFORM_NAME, textureScale ); + mActorForInput1.RegisterProperty( COEFFICIENT_UNIFORM_NAME, Vector3( 2.f, -1.f, -1.f ) ); + // set EMBOSS custom shader + mActorForInput1.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + mRootActor.Add( mActorForInput1 ); - mActorForInput2 = ImageActor::New( mInputImage ); + mActorForInput2 = Toolkit::ImageView::New( mInputImage ); mActorForInput2.SetParentOrigin( ParentOrigin::CENTER ); mActorForInput2.SetSize(mTargetSize); - mActorForInput2.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - mActorForInput2.SetColor( Color::WHITE ); - - mActorForEmboss1 = ImageActor::New( mImageForEmboss1 ); - mActorForEmboss1.SetParentOrigin( ParentOrigin::CENTER ); - mActorForEmboss1.SetSize(mTargetSize); - mActorForEmboss1.SetColor( Color::BLACK ); - mActorForEmboss1.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) ); - - mActorForEmboss2 = ImageActor::New( mImageForEmboss2 ); - mActorForEmboss2.SetParentOrigin( ParentOrigin::CENTER ); - mActorForEmboss2.SetSize(mTargetSize); - mActorForEmboss2.SetColor( Color::WHITE ); - mActorForEmboss2.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) ); + mActorForInput2.RegisterProperty( TEX_SCALE_UNIFORM_NAME, textureScale ); + mActorForInput2.RegisterProperty( COEFFICIENT_UNIFORM_NAME, Vector3( -1.f, -1.f, 2.f ) ); + // set EMBOSS custom shader + mActorForInput2.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + mRootActor.Add( mActorForInput2 ); mActorForComposite = Actor::New(); mActorForComposite.SetParentOrigin( ParentOrigin::CENTER ); mActorForComposite.SetSize(mTargetSize); - mActorForComposite.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - - // create custom shader effect - std::ostringstream embossFragmentSource1; - if( mDebugRender ) - { - embossFragmentSource1 << "#define DEBUG_RENDER\n"; - } - embossFragmentSource1 << EMBOSS_FRAGMENT_SOURCE1; - ShaderEffect effect1 = ShaderEffect::New( "", embossFragmentSource1.str() ); - mActorForInput1.SetShaderEffect( effect1 ); - effect1.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f ); - - std::ostringstream embossFragmentSource2; - if( mDebugRender ) - { - embossFragmentSource2 << "#define DEBUG_RENDER\n"; - } - embossFragmentSource2 << EMBOSS_FRAGMENT_SOURCE2; - ShaderEffect effect2 = ShaderEffect::New( "", embossFragmentSource2.str() ); - mActorForInput2.SetShaderEffect( effect2 ); - effect2.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f ); + mActorForComposite.SetColor( Color::BLACK ); + + customShader[ "fragmentShader" ] = COMPOSITE_FRAGMENT_SOURCE; + rendererMap[ "shader"] = customShader; + Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + mRendererForEmboss1 = rendererFactory.GetControlRenderer( mImageForEmboss1 ); + mRendererForEmboss2 = rendererFactory.GetControlRenderer( mImageForEmboss2 ); + // set COMPOSITE custom shader to both renderers + rendererFactory.ResetRenderer( mRendererForEmboss1, mActorForComposite, rendererMap); + rendererFactory.ResetRenderer( mRendererForEmboss2, mActorForComposite, rendererMap); + // apply renderers to the actor + mRendererForEmboss1.SetOnStage( mActorForComposite ); + mRendererForEmboss2.SetOnStage( mActorForComposite ); + mActorForComposite.GetRendererAt(0).RegisterProperty( COLOR_UNIFORM_NAME, Color::BLACK ); + mActorForComposite.GetRendererAt(1).RegisterProperty( COLOR_UNIFORM_NAME, Color::WHITE ); + mRootActor.Add( mActorForComposite ); SetupCamera(); CreateRenderTasks(); - - mRootActor.Add( mActorForInput1 ); - mRootActor.Add( mActorForInput2 ); - mRootActor.Add( mActorForComposite ); - mActorForComposite.Add( mActorForEmboss1 ); - mActorForComposite.Add( mActorForEmboss2 ); - mRootActor.Add( mCameraActor ); } void EmbossFilter::Disable() @@ -214,10 +163,12 @@ void EmbossFilter::Disable() if( mActorForComposite ) { + mRendererForEmboss1.SetOffStage( mActorForComposite ); + mRendererForEmboss2.SetOffStage( mActorForComposite ); + mRendererForEmboss1.Reset(); + mRendererForEmboss2.Reset(); mRootActor.Remove( mActorForComposite ); mActorForComposite.Reset(); - mActorForEmboss1.Reset(); - mActorForEmboss2.Reset(); } RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); @@ -258,30 +209,12 @@ void EmbossFilter::SetSize( const Vector2& size ) { mActorForInput2.SetSize(mTargetSize); } - if( mActorForEmboss1 ) - { - mActorForEmboss1.SetSize(mTargetSize); - } - if( mActorForEmboss2 ) - { - mActorForEmboss2.SetSize(mTargetSize); - } if( mActorForComposite ) { mActorForComposite.SetSize(mTargetSize); } } -void EmbossFilter::SetupCamera() -{ - // Create and place a camera for the embossing render, corresponding to its render target size - mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - mCameraActor.SetNearClippingPlane(1.0f); - mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height); - mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor - mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f))); -} - void EmbossFilter::CreateRenderTasks() { RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); diff --git a/dali-toolkit/internal/filters/emboss-filter.h b/dali-toolkit/internal/filters/emboss-filter.h index c912428..2c811f1 100644 --- a/dali-toolkit/internal/filters/emboss-filter.h +++ b/dali-toolkit/internal/filters/emboss-filter.h @@ -19,9 +19,9 @@ */ // EXTERNAL INCLUDES -#include -#include #include +#include +#include // INTERNAL INCLUDES #include "image-filter.h" @@ -66,11 +66,6 @@ public: // From ImageFilter private: /** - * Setup position and parameters for camera - */ - void SetupCamera(); - - /** * Setup render tasks for blur */ void CreateRenderTasks(); @@ -81,17 +76,16 @@ private: private: // Attributes - RenderTask mRenderTaskForEmboss1; - RenderTask mRenderTaskForEmboss2; - RenderTask mRenderTaskForOutput; - FrameBufferImage mImageForEmboss1; - FrameBufferImage mImageForEmboss2; - CameraActor mCameraActor; - ImageActor mActorForInput1; - ImageActor mActorForInput2; - ImageActor mActorForEmboss1; - ImageActor mActorForEmboss2; - Actor mActorForComposite; + RenderTask mRenderTaskForEmboss1; + RenderTask mRenderTaskForEmboss2; + RenderTask mRenderTaskForOutput; + FrameBufferImage mImageForEmboss1; + FrameBufferImage mImageForEmboss2; + Toolkit::ImageView mActorForInput1; + Toolkit::ImageView mActorForInput2; + Toolkit::ControlRenderer mRendererForEmboss1; + Toolkit::ControlRenderer mRendererForEmboss2; + Actor mActorForComposite; }; // class EmbossFilter } // namespace Internal diff --git a/dali-toolkit/internal/filters/image-filter.cpp b/dali-toolkit/internal/filters/image-filter.cpp index 80e69c2..f564c96 100644 --- a/dali-toolkit/internal/filters/image-filter.cpp +++ b/dali-toolkit/internal/filters/image-filter.cpp @@ -31,15 +31,14 @@ namespace Internal namespace { - +const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; } // namespace ImageFilter::ImageFilter() : mBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ), mTargetSize( Vector2::ZERO ), mPixelFormat( Pixel::RGBA8888 ), - mRefreshOnDemand( false ), - mDebugRender( false ) + mRefreshOnDemand( false ) { } @@ -116,11 +115,28 @@ void ImageFilter::SetBackgroundColor( const Vector4& color ) mBackgroundColor = color; } -void ImageFilter::RenderDebug( bool flag ) +void ImageFilter::SetupCamera() { - mDebugRender = flag; + if( !mCameraActor ) + { + // create a camera for the render task, corresponding to its render target size + mCameraActor = CameraActor::New(mTargetSize); + mCameraActor.SetParentOrigin(ParentOrigin::CENTER); + mCameraActor.SetInvertYAxis( true ); + mRootActor.Add( mCameraActor ); + } + else + { + // place the camera for the render task, corresponding to its render target size + mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); + mCameraActor.SetNearClippingPlane(1.0f); + mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height); + mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor + mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f))); + } } + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/filters/image-filter.h b/dali-toolkit/internal/filters/image-filter.h index bc4b164..3a4fac9 100644 --- a/dali-toolkit/internal/filters/image-filter.h +++ b/dali-toolkit/internal/filters/image-filter.h @@ -19,6 +19,7 @@ */ // EXTERNAL INCLUDES +#include // INTERNAL INCLUDES #include @@ -136,22 +137,24 @@ public: */ void SetBackgroundColor( const Vector4& color ); +protected: + /** - * Enable optional debug output in the shader - * @param[in] flag Set true to enable, dalse to disable. + * Setup position and parameters for camera */ - void RenderDebug( bool flag ); + void SetupCamera(); protected: Image mInputImage; FrameBufferImage mOutputImage; FilterKernel mKernel; Actor mRootActor; + CameraActor mCameraActor; Vector4 mBackgroundColor; Vector2 mTargetSize; Pixel::Format mPixelFormat; bool mRefreshOnDemand; - bool mDebugRender; + }; // class Imagefilter } // namespace Internal diff --git a/dali-toolkit/internal/filters/spread-filter.cpp b/dali-toolkit/internal/filters/spread-filter.cpp index d0b54f9..de205b6 100644 --- a/dali-toolkit/internal/filters/spread-filter.cpp +++ b/dali-toolkit/internal/filters/spread-filter.cpp @@ -19,9 +19,9 @@ #include "spread-filter.h" // EXTERNAL INCLUDES -#include #include #include +#include #include // INTERNAL INCLUDES @@ -38,38 +38,29 @@ namespace Internal namespace { -const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; - const char* const SPREAD_FRAGMENT_SOURCE = { "precision highp float;\n" - "uniform float uSpread;\n" + "varying mediump vec2 vTexCoord;\n" + "uniform sampler2D sTexture;\n" + "uniform int uSpread;\n" "uniform vec2 uTexScale;\n" "void main()\n" "{\n" " vec4 color = texture2D( sTexture, vTexCoord);\n" - "# ifdef DEBUG_RENDER\n" - " if( vTexCoord.s < 0.495 )\n" - " {\n" - "# endif //def DEBUG_RENDER\n" - " int spread = int(uSpread);\n" - " for( int i = 1; i <= spread; ++i )\n" - " {\n" - " vec2 offset = uTexScale * float(i);\n" - " color = max( texture2D( sTexture, vTexCoord + offset), color );\n" - " color = max( texture2D( sTexture, vTexCoord - offset), color );\n" - " }\n" - "# ifdef DEBUG_RENDER\n" - " }\n" - " else if( vTexCoord.s <= 0.505 )\n" + " for( int i = 1; i <= uSpread; ++i )\n" " {\n" - " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n" + " vec2 offset = uTexScale * float(i);\n" + " color = max( texture2D( sTexture, vTexCoord + offset), color );\n" + " color = max( texture2D( sTexture, vTexCoord - offset), color );\n" " }\n" - "# endif //def DEBUG_RENDER\n" " gl_FragColor = color;\n" "}\n" }; +const char* const SPREAD_UNIFORM_NAME( "uSpread" ); +const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" ); + } // namespace @@ -90,44 +81,35 @@ void SpreadFilter::SetSpread( float spread ) void SpreadFilter::Enable() { - mCameraActor = CameraActor::New(); - mCameraActor.SetParentOrigin(ParentOrigin::CENTER); - // create actor to render input with applied emboss effect - mActorForInput = ImageActor::New( mInputImage ); + mActorForInput = Toolkit::ImageView::New( mInputImage ); mActorForInput.SetParentOrigin( ParentOrigin::CENTER ); mActorForInput.SetSize(mTargetSize); - mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); + // register properties as shader uniforms + mActorForInput.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread ); + mActorForInput.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 1.0f / mTargetSize.width, 0.0f ) ); // create internal offscreen for result of horizontal pass mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED ); - // create an actor to render mImageForHorz for vertical blur pass - mActorForHorz = ImageActor::New( mImageForHorz ); + mActorForHorz = Toolkit::ImageView::New( mImageForHorz ); mActorForHorz.SetParentOrigin( ParentOrigin::CENTER ); mActorForHorz.SetSize(mTargetSize); - mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); - - mRootActor.Add( mActorForInput ); - mRootActor.Add( mActorForHorz ); - mRootActor.Add( mCameraActor ); + // register properties as shader uniforms + mActorForHorz.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread ); + mActorForHorz.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 0.0f, 1.0f / mTargetSize.height ) ); - std::ostringstream fragmentSource; - if( mDebugRender ) - { - fragmentSource << "#define DEBUG_RENDER\n"; - } - fragmentSource << SPREAD_FRAGMENT_SOURCE; + Property::Map customShader; + customShader[ "fragmentShader" ] = SPREAD_FRAGMENT_SOURCE; + Property::Map rendererMap; + rendererMap.Insert( "shader", customShader ); - mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() ); - mActorForInput.SetShaderEffect( mShaderForHorz ); - mShaderForHorz.SetUniform( "uSpread", mSpread ); - mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) ); + // set SPREAD custom shader + mActorForInput.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); + mActorForHorz.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap ); - mShaderForVert = ShaderEffect::New( "", fragmentSource.str() ); - mActorForHorz.SetShaderEffect( mShaderForVert ); - mShaderForVert.SetUniform( "uSpread", mSpread ); - mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) ); + mRootActor.Add( mActorForInput ); + mRootActor.Add( mActorForHorz ); SetupCamera(); CreateRenderTasks(); @@ -196,16 +178,6 @@ void SpreadFilter::SetSize( const Vector2& size ) } } -void SpreadFilter::SetupCamera() -{ - // Create and place a camera for the embossing render, corresponding to its render target size - mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - mCameraActor.SetNearClippingPlane(1.0f); - mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height); - mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor - mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f))); -} - void SpreadFilter::CreateRenderTasks() { RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); diff --git a/dali-toolkit/internal/filters/spread-filter.h b/dali-toolkit/internal/filters/spread-filter.h index 5f5d857..3ef2155 100644 --- a/dali-toolkit/internal/filters/spread-filter.h +++ b/dali-toolkit/internal/filters/spread-filter.h @@ -19,10 +19,8 @@ */ // EXTERNAL INCLUDES -#include -#include #include -#include +#include // INTERNAL INCLUDES #include "image-filter.h" @@ -72,10 +70,6 @@ public: // From ImageFilter virtual void SetSize( const Vector2& size ); private: - /** - * Setup position and parameters for camera - */ - void SetupCamera(); /** * Setup render tasks for blur @@ -87,19 +81,17 @@ private: SpreadFilter& operator=( const SpreadFilter& ); private: // Attributes - int mSpread; - CameraActor mCameraActor; // To perform horizontal spread from mInputImage to mImageForHorz - RenderTask mRenderTaskForHorz; - ImageActor mActorForInput; - FrameBufferImage mImageForHorz; - ShaderEffect mShaderForHorz; + RenderTask mRenderTaskForHorz; + Toolkit::ImageView mActorForInput; + FrameBufferImage mImageForHorz; // To perform vertical spread from mImageForHorz to mOutputImage - RenderTask mRenderTaskForVert; - ImageActor mActorForHorz; - ShaderEffect mShaderForVert; + RenderTask mRenderTaskForVert; + Toolkit::ImageView mActorForHorz; + + int mSpread; }; // class SpreadFilter } // namespace Internal -- 2.7.4