Allow to set render effect for off-scene control + Auto deactivate if invisible 51/315351/3
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 30 Jul 2024 12:29:57 +0000 (21:29 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 31 Jul 2024 11:42:14 +0000 (20:42 +0900)
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 <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp
dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp
dali-toolkit/internal/controls/render-effects/blur-effect-impl.h
dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp
dali-toolkit/internal/controls/render-effects/render-effect-impl.h
dali-toolkit/public-api/controls/control-impl.cpp

index bc33709..d20fd93 100644 (file)
@@ -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;
+}
index ac46a2e..52ea850 100644 (file)
@@ -21,7 +21,7 @@
 // EXTERNAL INCLUDES
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
-#include <dali/devel-api/common/stage.h>
+#include <dali/integration-api/debug.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/public-api/rendering/renderer.h>
 #include <dali/public-api/rendering/shader.h>
@@ -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<int>(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<int>(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<Property::Map>(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();
index 5e963ba..7234120 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/scene-holder.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/object/weak-handle.h>
+#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/rendering/frame-buffer.h>
+#include <string>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/render-effects/render-effect-impl.h>
 #include <dali-toolkit/public-api/controls/render-effects/background-blur-effect.h>
@@ -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<Integration::SceneHolder> 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
index 332ab76..f5e38e4 100644 (file)
 // CLASS HEADER
 #include <dali-toolkit/internal/controls/render-effects/render-effect-impl.h>
 
+// EXTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/scene-holder.h>
+#include <dali/integration-api/debug.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/control/control-renderers.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
@@ -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<int>(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<Vector2>(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<int>(Actor::Property::ID) : -1);
+
+    if(mOwnerControl)
+    {
+      mTargetSize = mOwnerControl.GetProperty<Vector2>(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<int>(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<Vector2>(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<int>(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<int>(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<bool>(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<bool>(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<int>(Actor::Property::ID) : -1, ret);
+
+  return ret;
+}
+
+void RenderEffectImpl::OnSizeSet(PropertyNotification& source)
+{
+  if(mOwnerControl)
+  {
+    mTargetSize = mOwnerControl.GetCurrentProperty<Vector2>(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<int>(Actor::Property::ID) : -1, visible);
+  if(visible)
+  {
+    Activate();
+  }
+  else
+  {
+    Deactivate();
+  }
+}
+
 } // namespace Internal
 } // namespace Toolkit
 } // namespace Dali
index 40f4743..9e1eb4e 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDE
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-notification.h>
+#include <dali/public-api/object/weak-handle.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <dali/public-api/signals/connection-tracker.h>
+
 //INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/render-effects/render-effect.h>
 
-// EXTERNAL INCLUDE
-#include <dali/public-api/dali-core.h>
-
 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
 
index 8513e2f..12236a8 100644 (file)
@@ -174,27 +174,29 @@ void Control::SetRenderEffect(Toolkit::RenderEffect effect)
     ClearRenderEffect();
     mImpl->mRenderEffect = effect;
 
-    BaseObject&                          handle = effect.GetBaseObject();
-    Toolkit::Internal::RenderEffectImpl* object = dynamic_cast<Toolkit::Internal::RenderEffectImpl*>(&handle);
-    DALI_ASSERT_ALWAYS(object && "Not a valid RenderEffect set.");
+    if(effect)
+    {
+      Toolkit::Internal::RenderEffectImpl* object = dynamic_cast<Toolkit::Internal::RenderEffectImpl*>(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<Toolkit::Internal::RenderEffectImpl*>(&handle);
-
-  if(object)
+  if(mImpl->mRenderEffect)
   {
-    object->Deactivate();
-    object->ClearOwnerControl();
+    Toolkit::Internal::RenderEffectImpl* object = dynamic_cast<Toolkit::Internal::RenderEffectImpl*>(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;
 }