From 73d3885d000117305d67bbd0af47ecedd89dbcfc Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 30 Jul 2024 21:29:57 +0900 Subject: [PATCH] Allow to set render effect for off-scene control + Auto deactivate if invisible Let we don't activate the render effect if owner control is not on scene. And also, auto deactivate if view is invisible + auto activate if view is visible again. And Deactivate & Activate is scensitive as changeness of owner control, Let we Deactivate first before we change the owner control TODO : Currently we don't consider the SceneHolder's visibility. It will be fixed after InheritVisibilityChanged signal consider Scene's visibility. Change-Id: If1f3cdc176a28135b9f7a3184e736b375357a1b3 Signed-off-by: Eunki, Hong --- .../src/dali-toolkit/utc-Dali-RenderEffect.cpp | 246 +++++++++++++++++++-- .../controls/render-effects/blur-effect-impl.cpp | 112 ++++++---- .../controls/render-effects/blur-effect-impl.h | 38 ++-- .../controls/render-effects/render-effect-impl.cpp | 163 ++++++++++++-- .../controls/render-effects/render-effect-impl.h | 96 ++++++-- dali-toolkit/public-api/controls/control-impl.cpp | 31 +-- 6 files changed, 565 insertions(+), 121 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp index bc33709..d20fd93 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp @@ -74,12 +74,12 @@ int UtcDaliRenderEffectActivateP01(void) control.Add(childControl); RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(1u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); childControl.SetRenderEffect(BackgroundBlurEffect::New()); taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); END_TEST; } @@ -100,7 +100,7 @@ int UtcDaliRenderEffectActivateP02(void) control.SetRenderEffect(blurEffect); RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); Control control2 = Control::New(); control2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); @@ -109,7 +109,7 @@ int UtcDaliRenderEffectActivateP02(void) control2.SetRenderEffect(blurEffect); taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); END_TEST; } @@ -130,13 +130,13 @@ int UtcDaliRenderEffectDeactivateP(void) control.SetRenderEffect(BackgroundBlurEffect::New()); RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); - DALI_TEST_CHECK(count + 1 == control.GetRendererCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); control.ClearRenderEffect(); taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(1u == taskList.GetTaskCount()); - DALI_TEST_CHECK(count == control.GetRendererCount()); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); END_TEST; } @@ -154,9 +154,9 @@ int UtcDaliRenderEffectDeactivateN(void) scene.Add(control); RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(1u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); control.ClearRenderEffect(); // Nothing happens - DALI_TEST_CHECK(1u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); END_TEST; } @@ -177,13 +177,13 @@ int UtcDaliRenderEffectActivateDeactivateInplace(void) control.SetRenderEffect(blurEffect); RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); control.ClearRenderEffect(); control.SetRenderEffect(blurEffect); control.ClearRenderEffect(); control.SetRenderEffect(blurEffect); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); END_TEST; } @@ -205,7 +205,7 @@ int UtcDaliRenderEffectReassign(void) control.SetRenderEffect(blurEffect); // Duplicate actions will be ignored control.SetRenderEffect(blurEffect); // Duplicate actions will be ignored RenderTaskList taskList = scene.GetRenderTaskList(); - DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); END_TEST; } @@ -305,3 +305,223 @@ int UtcDaliRenderEffectInvalidTargetSize(void) END_TEST; } + +int UtcDaliRenderEffectControlSceneOnAndSceneOff01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectControlSceneOnAndSceneOff01"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + uint32_t count = control.GetRendererCount(); + + // Add render effect during scene off. + control.SetRenderEffect(BackgroundBlurEffect::New()); + + RenderTaskList taskList = scene.GetRenderTaskList(); + + // Still render effect is not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + scene.Add(control); + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.Unparent(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + scene.Add(control); + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.Unparent(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.ClearRenderEffect(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + scene.Add(control); + // Render effect not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + END_TEST; +} + +int UtcDaliRenderEffectControlSceneOnAndSceneOff02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectControlSceneOnAndSceneOff02"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + uint32_t count = control.GetRendererCount(); + scene.Add(control); + + // Add render effect during scene on. + control.SetRenderEffect(BackgroundBlurEffect::New()); + + RenderTaskList taskList = scene.GetRenderTaskList(); + + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.Unparent(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + scene.Add(control); + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.Unparent(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.ClearRenderEffect(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + scene.Add(control); + // Render effect not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + END_TEST; +} + +int UtcDaliRenderEffectControlVisiblityChanged01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectControlVisiblityChanged01"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + uint32_t count = control.GetRendererCount(); + scene.Add(control); + + // Add render effect during invisible. + control.SetProperty(Actor::Property::VISIBLE, false); + control.SetRenderEffect(BackgroundBlurEffect::New()); + + RenderTaskList taskList = scene.GetRenderTaskList(); + + // Still render effect is not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + // Render effect activated. + control.SetProperty(Actor::Property::VISIBLE, true); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.SetProperty(Actor::Property::VISIBLE, false); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.Unparent(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + // Render effect still deactivated. + control.SetProperty(Actor::Property::VISIBLE, true); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + // Render effect activated. + scene.Add(control); + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.SetProperty(Actor::Property::VISIBLE, false); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.ClearRenderEffect(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.SetProperty(Actor::Property::VISIBLE, true); + // Render effect not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + END_TEST; +} + +int UtcDaliRenderEffectControlVisiblityChanged02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectControlVisiblityChanged02"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + uint32_t count = control.GetRendererCount(); + scene.Add(control); + + // Add render effect during scene on. + control.SetRenderEffect(BackgroundBlurEffect::New()); + + RenderTaskList taskList = scene.GetRenderTaskList(); + + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.SetProperty(Actor::Property::VISIBLE, false); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.SetProperty(Actor::Property::VISIBLE, true); + // Render effect activated. + DALI_TEST_EQUALS(4u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count + 1, control.GetRendererCount(), TEST_LOCATION); + + // Render effect deactivated. + control.SetProperty(Actor::Property::VISIBLE, false); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.ClearRenderEffect(); + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + control.SetProperty(Actor::Property::VISIBLE, true); + // Render effect not activated. + DALI_TEST_EQUALS(1u, taskList.GetTaskCount(), TEST_LOCATION); + DALI_TEST_EQUALS(count, control.GetRendererCount(), TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp index ac46a2e..52ea850 100644 --- a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp @@ -21,7 +21,7 @@ // EXTERNAL INCLUDES #include #include -#include +#include #include #include #include @@ -46,13 +46,16 @@ namespace Toolkit { namespace Internal { +#ifdef DEBUG_ENABLED +extern Debug::Filter* gRenderEffectLogFilter; ///< Define at render-effect-impl.cpp +#endif + BlurEffectImpl::BlurEffectImpl(bool isBackground) : RenderEffectImpl(), mInternalRoot(Actor::New()), mDownscaleFactor(BLUR_EFFECT_DOWNSCALE_FACTOR), mPixelRadius(BLUR_EFFECT_PIXEL_RADIUS), mBellCurveWidth(0.001f), - mIsActivated(false), mIsBackground(isBackground) { } @@ -63,7 +66,6 @@ BlurEffectImpl::BlurEffectImpl(float downscaleFactor, uint32_t blurRadius, bool mDownscaleFactor(downscaleFactor), mPixelRadius((blurRadius >> 2) + 1), mBellCurveWidth(0.001f), - mIsActivated(false), mIsBackground(isBackground) { DALI_ASSERT_ALWAYS(downscaleFactor <= 1.0 && 0.0 < downscaleFactor); @@ -87,7 +89,7 @@ BlurEffectImplPtr BlurEffectImpl::New(float downscaleFactor, uint32_t blurRadius return handle; } -void BlurEffectImpl::Initialize() +void BlurEffectImpl::OnInitialize() { mRenderFullSizeCamera = CameraActor::New(); mRenderFullSizeCamera.SetInvertYAxis(true); @@ -123,6 +125,8 @@ void BlurEffectImpl::Initialize() } mBellCurveWidth = sigma; + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Verbose, "[BlurEffect:%p] mBellCurveWidth calculated! [radius:%u][sigma:%f]\n", this, mPixelRadius, mBellCurveWidth); + ////////////////////////////////////////////////////// // Create actors mInternalRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); @@ -142,41 +146,15 @@ void BlurEffectImpl::Initialize() mInternalRoot.Add(mVerticalBlurActor); } -Vector2 BlurEffectImpl::GetTargetSizeForValidTexture() +void BlurEffectImpl::OnActivate() { - Vector2 size = GetTargetSize(); - if(size == Vector2::ZERO) - { - size = GetOwnerControl().GetNaturalSize(); - } - - if(size == Vector2::ZERO || size.x < 0.0f || size.y < 0.0f) - { - return Vector2::ZERO; - } - - const uint32_t maxTextureSize = Dali::GetMaxTextureSize(); - if(uint32_t(size.x) > maxTextureSize || uint32_t(size.y) > maxTextureSize) - { - uint32_t denominator = std::max(size.x, size.y); - size.x = (size.x * maxTextureSize / denominator); - size.y = (size.y * maxTextureSize / denominator); - } - return size; -} - -void BlurEffectImpl::Activate() -{ - if(mIsActivated) - { - return; - } - mIsActivated = true; Toolkit::Control ownerControl = GetOwnerControl(); DALI_ASSERT_ALWAYS(ownerControl && "Set the owner of RenderEffect before you activate."); // Get/Set sizes Vector2 size = GetTargetSizeForValidTexture(); + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[BlurEffect:%p] OnActivated! [ID:%d][size:%fx%f]\n", this, ownerControl ? ownerControl.GetProperty(Actor::Property::ID) : -1, size.x, size.y); + if(size == Vector2::ZERO) { return; @@ -192,7 +170,17 @@ void BlurEffectImpl::Activate() downsampledHeight = 1u; } - RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); + Integration::SceneHolder sceneHolder = Integration::SceneHolder::Get(ownerControl); + if(DALI_UNLIKELY(!sceneHolder)) + { + DALI_LOG_ERROR("BlurEffect Could not be activated due to ownerControl's SceneHolder is not exist\n"); + return; + } + + // Keep sceneHolder as week handle. + mPlacementSceneHolder = sceneHolder; + + RenderTaskList taskList = sceneHolder.GetRenderTaskList(); // Prepare resource // original texture output @@ -229,7 +217,7 @@ void BlurEffectImpl::Activate() mSourceRenderTask = taskList.CreateTask(); if(mIsBackground) { - mSourceRenderTask.SetSourceActor(Stage::GetCurrent().GetRootLayer()); + mSourceRenderTask.SetSourceActor(sceneHolder.GetRootLayer()); mSourceRenderTask.RenderUntil(ownerControl); } else @@ -277,9 +265,15 @@ void BlurEffectImpl::Activate() ownerControl.Add(mInternalRoot); } -void BlurEffectImpl::Deactivate() +void BlurEffectImpl::OnDeactivate() { - mIsActivated = false; + auto ownerControl = GetOwnerControl(); + if(DALI_LIKELY(ownerControl)) + { + Renderer renderer = GetTargetRenderer(); + ownerControl.RemoveRenderer(renderer); + } + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[BlurEffect:%p] OnDeactivated! [ID:%d]\n", this, ownerControl ? ownerControl.GetProperty(Actor::Property::ID) : -1); mInternalRoot.Unparent(); @@ -287,10 +281,42 @@ void BlurEffectImpl::Deactivate() mTemporaryFrameBuffer.Reset(); mSourceFrameBuffer.Reset(); - RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); - taskList.RemoveTask(mHorizontalBlurTask); - taskList.RemoveTask(mVerticalBlurTask); - taskList.RemoveTask(mSourceRenderTask); + auto sceneHolder = mPlacementSceneHolder.GetHandle(); + if(DALI_LIKELY(sceneHolder)) + { + RenderTaskList taskList = sceneHolder.GetRenderTaskList(); + taskList.RemoveTask(mHorizontalBlurTask); + taskList.RemoveTask(mVerticalBlurTask); + taskList.RemoveTask(mSourceRenderTask); + mPlacementSceneHolder.Reset(); + } + + mHorizontalBlurTask.Reset(); + mVerticalBlurTask.Reset(); + mSourceRenderTask.Reset(); +} + +Vector2 BlurEffectImpl::GetTargetSizeForValidTexture() const +{ + Vector2 size = GetTargetSize(); + if(size == Vector2::ZERO) + { + size = GetOwnerControl().GetNaturalSize(); + } + + if(size == Vector2::ZERO || size.x < 0.0f || size.y < 0.0f) + { + return Vector2::ZERO; + } + + const uint32_t maxTextureSize = Dali::GetMaxTextureSize(); + if(uint32_t(size.x) > maxTextureSize || uint32_t(size.y) > maxTextureSize) + { + uint32_t denominator = std::max(size.x, size.y); + size.x = (size.x * maxTextureSize / denominator); + size.y = (size.y * maxTextureSize / denominator); + } + return size; } void BlurEffectImpl::SetShaderConstants(float downsampledWidth, float downsampledHeight) @@ -355,13 +381,15 @@ std::string BlurEffectImpl::GetSampleWeightsPropertyName(unsigned int index) con void BlurEffectImpl::SynchronizeBackgroundCornerRadius() { + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Verbose, "[BlurEffect:%p] Synchronize background corner radius\n", this); + DALI_ASSERT_ALWAYS(GetOwnerControl() && "You should first SetRenderEffect(), then set its background property map"); Property::Map map = GetOwnerControl().GetProperty(Toolkit::Control::Property::BACKGROUND); Vector4 radius = Vector4::ZERO; map[Toolkit::DevelVisual::Property::CORNER_RADIUS].Get(radius); - Visual::Transform::Policy::Type policy; + Visual::Transform::Policy::Type policy{Visual::Transform::Policy::ABSOLUTE}; map[Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY].Get(policy); Renderer renderer = GetTargetRenderer(); diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h index 5e963ba..7234120 100644 --- a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h @@ -18,6 +18,15 @@ * */ +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include + // INTERNAL INCLUDES #include #include @@ -60,16 +69,6 @@ public: */ static BlurEffectImplPtr New(float downscaleFactor, uint32_t blurRadius, bool isBackground); - /** - * @brief Activates blur effect - */ - void Activate() override; - - /** - * @brief Dectivates blur effect - */ - void Deactivate() override; - protected: /** * @brief Creates an uninitialized blur effect implementation @@ -91,9 +90,19 @@ protected: virtual ~BlurEffectImpl(); /** - * @brief Initializes effect + * @brief Initializes blur effect */ - void Initialize() override; + void OnInitialize() override; + + /** + * @brief Activates blur effect + */ + void OnActivate() override; + + /** + * @brief Dectivates blur effect + */ + void OnDeactivate() override; private: // Inner functions @@ -103,7 +112,7 @@ private: * @return A valid version of mTargetSize, Vector2::ZERO otherwise. * @note The return value is a copy, not mTargetSize itself. */ - Vector2 GetTargetSizeForValidTexture(); + Vector2 GetTargetSizeForValidTexture() const; /** * @brief Calculates gaussian weight @@ -153,6 +162,8 @@ private: // Resource FrameBuffer mInputBackgroundFrameBuffer; // Input. Background. What to blur. + WeakHandle mPlacementSceneHolder; + Actor mInternalRoot; Actor mHorizontalBlurActor; RenderTask mHorizontalBlurTask; @@ -168,7 +179,6 @@ private: uint32_t mPixelRadius; float mBellCurveWidth; - bool mIsActivated : 1; bool mIsBackground : 1; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp index 332ab76..f5e38e4 100644 --- a/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp +++ b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp @@ -18,6 +18,10 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include +#include + // INTERNAL INCLUDES #include #include @@ -33,8 +37,24 @@ namespace Toolkit { namespace Internal { +#if defined(DEBUG_ENABLED) +// Keep this log filter inside of Dali::Toolkit::Internal, so subclass of RenderEffect can also use this. +Debug::Filter* gRenderEffectLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_EFFECT"); +#endif + +RenderEffectImpl::RenderEffectImpl() +: mRenderer(), + mOwnerControl(), + mSizeNotification(), + mTargetSize(Vector2::ZERO), + mIsActivated(false) +{ + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Verbose, "[RenderEffect:%p] Constructor\n", this); +} + RenderEffectImpl::~RenderEffectImpl() { + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Verbose, "[RenderEffect:%p] Destructor. [ID:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1); if(mOwnerControl) { mOwnerControl.ClearRenderEffect(); @@ -43,42 +63,66 @@ RenderEffectImpl::~RenderEffectImpl() void RenderEffectImpl::SetOwnerControl(Dali::Toolkit::Control control) { - if(control && (control != mOwnerControl)) + if(mOwnerControl != control) { + // Clear previous owner control + ClearOwnerControl(); + mOwnerControl = control; - mTargetSize = mOwnerControl.GetProperty(Actor::Property::SIZE); - mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG); + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] SetOwnerControl [ID:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1); + + if(mOwnerControl) + { + mTargetSize = mOwnerControl.GetProperty(Actor::Property::SIZE); + if(!mRenderer) + { + mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG); + } + + mOwnerControl.InheritedVisibilityChangedSignal().Connect(this, &RenderEffectImpl::OnControlInheritedVisibilityChanged); + + mSizeNotification = mOwnerControl.AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION)); + mSizeNotification.NotifySignal().Connect(this, &RenderEffectImpl::OnSizeSet); - mSizeNotification = control.AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION)); - mSizeNotification.NotifySignal().Connect(this, &RenderEffectImpl::OnSizeSet); + Activate(); // Dev note : Activate after set the owner control. + } } } void RenderEffectImpl::ClearOwnerControl() { + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] ClearOwnerControl [ID:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1); if(mOwnerControl) { - Renderer renderer = GetTargetRenderer(); - mOwnerControl.RemoveRenderer(renderer); + Deactivate(); // Dev note : Deactivate before clearing the owner control. + + mOwnerControl.InheritedVisibilityChangedSignal().Disconnect(this, &RenderEffectImpl::OnControlInheritedVisibilityChanged); + mOwnerControl.RemovePropertyNotification(mSizeNotification); + mSizeNotification.Reset(); + + auto previousOwnerControl = mOwnerControl; mOwnerControl.Reset(); + + // Make previous owner don't have render effect, after make we don't have owner control now. + previousOwnerControl.ClearRenderEffect(); } } -Toolkit::Control RenderEffectImpl::GetOwnerControl() const +bool RenderEffectImpl::IsActivated() const { - return mOwnerControl; + return mIsActivated; } -void RenderEffectImpl::OnSizeSet(PropertyNotification& source) +void RenderEffectImpl::Initialize() { - if(mOwnerControl) - { - mTargetSize = mOwnerControl.GetCurrentProperty(Actor::Property::SIZE); - Deactivate(); - Activate(); - } + OnInitialize(); +} + +Toolkit::Control RenderEffectImpl::GetOwnerControl() const +{ + return mOwnerControl; } Renderer RenderEffectImpl::GetTargetRenderer() const @@ -91,6 +135,93 @@ Vector2 RenderEffectImpl::GetTargetSize() const return mTargetSize; } +void RenderEffectImpl::Activate() +{ + if(!IsActivated() && IsActivateValid()) + { + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] Activated! [ID:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1); + mIsActivated = true; + + // Activate logic for subclass. + OnActivate(); + } +} + +void RenderEffectImpl::Deactivate() +{ + if(IsActivated() || !IsActivateValid()) + { + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] Deactivated! [ID:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1); + mIsActivated = false; + + // Deactivate logic for subclass. + OnDeactivate(); + } +} + +bool RenderEffectImpl::IsActivateValid() const +{ + // Activate is valid if + // - Owner control is on scene + // - All actors of owner control are visible + // - The SceneHolder is exist, and it is visible + // TODO : Currently we don't check SceneHolder's visibility. + bool ret = false; + + if(mOwnerControl && mOwnerControl.GetProperty(Actor::Property::CONNECTED_TO_SCENE)) + { + Integration::SceneHolder sceneHolder = Integration::SceneHolder::Get(mOwnerControl); + if(sceneHolder) + { + ret = true; + + // Check visibility of owner control's parents. + // TODO : We'd better check the control visibility at core side. + // TODO : Window visibility will be consider at dali-core actor side in future. + Dali::Actor self = mOwnerControl; + while(self) + { + if(!self.GetProperty(Dali::Actor::Property::VISIBLE)) + { + ret = false; + break; + } + self = self.GetParent(); + } + } + } + + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Concise, "[RenderEffect:%p] IsActivateValid? [ID:%d][ret:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1, ret); + + return ret; +} + +void RenderEffectImpl::OnSizeSet(PropertyNotification& source) +{ + if(mOwnerControl) + { + mTargetSize = mOwnerControl.GetCurrentProperty(Actor::Property::SIZE); + if(IsActivated()) + { + Deactivate(); + Activate(); + } + } +} + +void RenderEffectImpl::OnControlInheritedVisibilityChanged(Actor actor, bool visible) +{ + DALI_LOG_INFO(gRenderEffectLogFilter, Debug::Concise, "[RenderEffect:%p] visibility changed [ID:%d][visible:%d]\n", this, mOwnerControl ? mOwnerControl.GetProperty(Actor::Property::ID) : -1, visible); + if(visible) + { + Activate(); + } + else + { + Deactivate(); + } +} + } // namespace Internal } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/internal/controls/render-effects/render-effect-impl.h b/dali-toolkit/internal/controls/render-effects/render-effect-impl.h index 40f4743..9e1eb4e 100644 --- a/dali-toolkit/internal/controls/render-effects/render-effect-impl.h +++ b/dali-toolkit/internal/controls/render-effects/render-effect-impl.h @@ -18,12 +18,18 @@ * */ +// EXTERNAL INCLUDE +#include +#include +#include +#include +#include +#include +#include + //INTERNAL INCLUDES #include -// EXTERNAL INCLUDE -#include - namespace Dali { namespace Toolkit @@ -38,16 +44,6 @@ class RenderEffectImpl : public BaseObject, public ConnectionTracker { public: /** - * @brief Activates effect on ownerControl - */ - virtual void Activate() = 0; - - /** - * @brief Deactivates effect - */ - virtual void Deactivate() = 0; - - /** * @brief Sets owner Control. Applies effect on the owner. * @param[in] control The owner control to apply RenderEffect. */ @@ -58,11 +54,17 @@ public: */ void ClearOwnerControl(); + /** + * @brief Get whether this effect activated or not. + * @return True if effect is activated. False otherwise. + */ + bool IsActivated() const; + protected: /** * @copydoc Dali::Toolkit::RenderEffect::RenderEffect */ - RenderEffectImpl() = default; + RenderEffectImpl(); /** * @copydoc Dali::Toolkit::RenderEffect::~RenderEffect @@ -74,7 +76,10 @@ protected: RenderEffectImpl& operator=(RenderEffectImpl&&) = delete; // no move() RenderEffectImpl& operator=(const RenderEffectImpl&) = delete; // no copy() - virtual void Initialize() = 0; + /** + * @brief Second-phase Initialization + */ + void Initialize(); /** * @brief Get target renderer @@ -84,11 +89,6 @@ protected: Renderer GetTargetRenderer() const; /** - * @brief Callback when the size changes. - */ - void OnSizeSet(PropertyNotification& source); - - /** * @brief The final size of the owner after resizing or relayouts. * @return mTargetSize */ @@ -100,12 +100,62 @@ protected: */ Toolkit::Control GetOwnerControl() const; + /// For sub classes +protected: + /** + * @brief Initialize sub classes effect + */ + virtual void OnInitialize() = 0; + + /** + * @brief Activates sub classes effect on ownerControl + */ + virtual void OnActivate() = 0; + + /** + * @brief Deactivates sub classes effect + */ + virtual void OnDeactivate() = 0; + private: - Dali::Renderer mRenderer; // An additional renderer for mOwnerControl - Dali::Toolkit::Control mOwnerControl; + /** + * @brief Activates effect on ownerControl + */ + void Activate(); - PropertyNotification mSizeNotification; // Resize/Relayout signal + /** + * @brief Deactivates effect + */ + void Deactivate(); + + /** + * @brief Check whether it is possible to activate effect or not. + * It will check various status, e.g. the control's visibility. + * @note This API don't consider mIsActivated + */ + bool IsActivateValid() const; + +private: + /** + * @brief Callback when the size changes. + */ + void OnSizeSet(PropertyNotification& source); + + /** + * @brief Callback when the visibility of the actor is changed. + * @param[in] actor The actor + * @param[in] visible Whether this actor is visible or not. + */ + void OnControlInheritedVisibilityChanged(Actor actor, bool visible); + +private: + Dali::Renderer mRenderer; // An additional renderer for mOwnerControl + Dali::Toolkit::Control mOwnerControl; ///< TODO : Make it as WeakHandle if mSizeNotification reference issue is fixed. + + PropertyNotification mSizeNotification; // Resize/Relayout signal. Vector2 mTargetSize; // The final size of mOwnerControl + + bool mIsActivated : 1; }; } // namespace Internal diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 8513e2f..12236a8 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -174,27 +174,29 @@ void Control::SetRenderEffect(Toolkit::RenderEffect effect) ClearRenderEffect(); mImpl->mRenderEffect = effect; - BaseObject& handle = effect.GetBaseObject(); - Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(&handle); - DALI_ASSERT_ALWAYS(object && "Not a valid RenderEffect set."); + if(effect) + { + Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(mImpl->mRenderEffect.GetObjectPtr()); + DALI_ASSERT_ALWAYS(object && "Not a valid RenderEffect set."); - Dali::Toolkit::Control ownerControl(GetOwner()); - object->SetOwnerControl(ownerControl); - object->Activate(); + Dali::Toolkit::Control ownerControl(GetOwner()); + object->SetOwnerControl(ownerControl); + } } } void Control::ClearRenderEffect() { - BaseObject& handle = mImpl->mRenderEffect.GetBaseObject(); - Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(&handle); - - if(object) + if(mImpl->mRenderEffect) { - object->Deactivate(); - object->ClearOwnerControl(); + Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(mImpl->mRenderEffect.GetObjectPtr()); + + if(object) + { + object->ClearOwnerControl(); + } + mImpl->mRenderEffect.Reset(); } - mImpl->mRenderEffect.Reset(); } void Control::SetResourceReady() @@ -437,6 +439,9 @@ Control::Control(ControlBehaviour behaviourFlags) Control::~Control() { + // Deactivate render effect before destroying the control impl + ClearRenderEffect(); + delete mImpl; } -- 2.7.4