Generalize RenderEffectImpl to OffScreenRendering 33/317633/8
authorjmm <j0064423.lee@samsung.com>
Mon, 6 Jan 2025 06:50:43 +0000 (15:50 +0900)
committerjmm <j0064423.lee@samsung.com>
Wed, 8 Jan 2025 05:31:34 +0000 (14:31 +0900)
Change-Id: I3e4213b825edd9382d91e45293974f8def980385
Signed-off-by: jmm <j0064423.lee@samsung.com>
14 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-RenderEffect-internal.cpp
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
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/offscreen-rendering-context.cpp [deleted file]
dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.h [deleted file]
dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp
dali-toolkit/internal/controls/render-effects/render-effect-impl.h
dali-toolkit/internal/file.list
dali-toolkit/public-api/controls/render-effects/render-effect.h

index bfa78dfb31476d380929287862866e84eebfef86..a6b9c531b401f02248a8dd688d4f0f043bec5593 100644 (file)
@@ -140,7 +140,6 @@ int UtcDaliInternalRenderEffectNewP(void)
 
   // Check that effect is not activate yet.
   Toolkit::Internal::TestRenderEffectImpl& impl = Toolkit::Internal::GetImplementation(testEffect);
-  DALI_TEST_EQUALS(impl.IsActivated(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(impl.mOnActivated, false, TEST_LOCATION);
   DALI_TEST_EQUALS(impl.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
@@ -150,96 +149,84 @@ int UtcDaliInternalRenderEffectNewP(void)
 int UtcDaliInternalRenderEffectGetOwnerControl01(void)
 {
   tet_infoline("UtcDaliInternalRenderEffecGetOwnerControl01");
+  ToolkitTestApplication application;
 
   Toolkit::TestRenderEffect testEffect = Toolkit::TestRenderEffect::New();
   DALI_TEST_CHECK(testEffect);
 
   // Check that effect prototype is not activated.
   Toolkit::Internal::TestRenderEffectImpl& prototype = Toolkit::Internal::GetImplementation(testEffect);
-  DALI_TEST_EQUALS(prototype.IsActivated(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.mOnActivated, false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
-  {
-    ToolkitTestApplication application;
-
-    Integration::Scene scene = application.GetScene();
+  Integration::Scene scene = application.GetScene();
 
-    Control control = Control::New();
-    control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-    control.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
-    scene.Add(control);
+  Control control = Control::New();
+  control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  control.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+  scene.Add(control);
 
-    tet_printf("Test effect set, and activate due to control scene on.\n");
-    control.SetRenderEffect(testEffect);
+  tet_printf("Test effect set, and activate due to control scene on.\n");
+  control.SetRenderEffect(testEffect);
 
-    Toolkit::Internal::TestRenderEffectImplPtr impl =
-      dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control.GetRenderEffect().GetObjectPtr());
+  Toolkit::Internal::TestRenderEffectImplPtr impl =
+    dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control.GetRenderEffect().GetObjectPtr());
 
-    { // Check that effect prototype is not activated,
-      DALI_TEST_EQUALS(impl == &prototype, false, TEST_LOCATION);
+  { // Check that effect prototype is not activated,
+    DALI_TEST_EQUALS(impl == &prototype, false, TEST_LOCATION);
 
-      DALI_TEST_EQUALS(prototype.IsActivated(), false, TEST_LOCATION);
-      DALI_TEST_EQUALS(prototype.mOnActivated, false, TEST_LOCATION);
-      DALI_TEST_EQUALS(prototype.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
+    DALI_TEST_EQUALS(prototype.mOnActivated, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(prototype.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
-      // but the effect is set and activated.
-      DALI_TEST_EQUALS(impl->IsActivated(), true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->mOnActivated, true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
-    }
+    // but the effect is set and activated.
+    DALI_TEST_EQUALS(impl->mOnActivated, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
+  }
 
-    control.Unparent();
+  control.Unparent();
 
-    {
-      DALI_TEST_EQUALS(impl->IsActivated(), false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
-    }
+  {
+    DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
+  }
 
-    scene.Add(control);
+  scene.Add(control);
 
-    {
-      DALI_TEST_EQUALS(impl->IsActivated(), true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->mOnActivated, true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
-    }
+  {
+    DALI_TEST_EQUALS(impl->mOnActivated, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl->GetOwnerControl(), control, TEST_LOCATION);
+  }
 
-    // Control released.
-    control.Unparent();
-    control.Reset();
+  // Control released.
+  control.Unparent();
+  control.Reset();
 
-    tet_printf("Test effect owner control is empty after control destructed.\n");
-    DALI_TEST_CHECK(testEffect);
+  tet_printf("Test effect owner control is empty after control destructed.\n");
+  DALI_TEST_CHECK(testEffect);
 
-    {
-      DALI_TEST_EQUALS(impl->IsActivated(), false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
-    }
+  {
+    DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
+  }
 
-    control = Control::New();
-    control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-    control.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
-    scene.Add(control);
+  control = Control::New();
+  control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  control.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+  scene.Add(control);
 
-    tet_printf("Test effect set again.\n");
-    control.SetRenderEffect(testEffect);
+  tet_printf("Test effect set again.\n");
+  control.SetRenderEffect(testEffect);
 
-    Toolkit::Internal::TestRenderEffectImplPtr impl2 =
-      dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control.GetRenderEffect().GetObjectPtr());
-    {
-      DALI_TEST_EQUALS(impl == impl2, false, TEST_LOCATION);
+  Toolkit::Internal::TestRenderEffectImplPtr impl2 =
+    dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control.GetRenderEffect().GetObjectPtr());
+  {
+    DALI_TEST_EQUALS(impl == impl2, false, TEST_LOCATION);
 
-      DALI_TEST_EQUALS(impl->IsActivated(), false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION); // may be false?
+    DALI_TEST_EQUALS(impl->mOnActivated, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION); // may be false?
 
-      DALI_TEST_EQUALS(impl2->IsActivated(), true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl2->mOnActivated, true, TEST_LOCATION);
-      DALI_TEST_EQUALS(impl2->GetOwnerControl(), control, TEST_LOCATION);
-    }
-    // Terminate application.
+    DALI_TEST_EQUALS(impl2->mOnActivated, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(impl2->GetOwnerControl(), control, TEST_LOCATION);
   }
 
   END_TEST;
@@ -267,68 +254,59 @@ int UtcDaliInternalRenderEffectGetOwnerControl02(void)
 
   // Check that effect is not activate yet.
   Toolkit::Internal::TestRenderEffectImpl& prototype = Toolkit::Internal::GetImplementation(testEffect);
-  DALI_TEST_EQUALS(prototype.IsActivated(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.mOnActivated, false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
   tet_printf("Test effect set, and activate due to control scene on.\n");
   control1.SetRenderEffect(testEffect);
 
-  Toolkit::Internal::TestRenderEffectImpl& impl1 =
-    *(dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control1.GetRenderEffect().GetObjectPtr()));
+  Toolkit::Internal::TestRenderEffectImplPtr impl1 =
+    dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control1.GetRenderEffect().GetObjectPtr());
 
-  DALI_TEST_EQUALS(&prototype == &impl1, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(prototype.IsActivated(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS(&prototype == impl1, false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.mOnActivated, false, TEST_LOCATION);
   DALI_TEST_EQUALS(prototype.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
-  DALI_TEST_EQUALS(impl1.IsActivated(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.mOnActivated, true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.GetOwnerControl(), control1, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->mOnActivated, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->GetOwnerControl(), control1, TEST_LOCATION);
 
   tet_printf("Test effect set to another control\n");
   control2.SetRenderEffect(testEffect);
 
-  Toolkit::Internal::TestRenderEffectImpl& impl2 =
-    *(dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control2.GetRenderEffect().GetObjectPtr()));
-  DALI_TEST_EQUALS(&impl1 == &impl2, false, TEST_LOCATION);
+  Toolkit::Internal::TestRenderEffectImplPtr impl2 =
+    dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control2.GetRenderEffect().GetObjectPtr());
+  DALI_TEST_EQUALS(impl1 == impl2, false, TEST_LOCATION);
 
-  DALI_TEST_EQUALS(impl2.IsActivated(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.mOnActivated, true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.GetOwnerControl(), control2, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->mOnActivated, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->GetOwnerControl(), control2, TEST_LOCATION);
 
   tet_printf("Test control1 call ClearRenderEffect don't have any effort to control2's effect\n");
   control1.ClearRenderEffect();
 
-  DALI_TEST_EQUALS(impl1.IsActivated(), false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.mOnActivated, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->mOnActivated, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
-  DALI_TEST_EQUALS(impl2.IsActivated(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.mOnActivated, true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.GetOwnerControl(), control2, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->mOnActivated, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->GetOwnerControl(), control2, TEST_LOCATION);
 
   tet_printf("Test control2 call ClearRenderEffect\n");
   control2.ClearRenderEffect();
 
-  DALI_TEST_EQUALS(impl2.IsActivated(), false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.mOnActivated, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl2.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->mOnActivated, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl2->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
   tet_printf("Reset control1 effect\n");
   control1.SetRenderEffect(testEffect);
 
-  Toolkit::Internal::TestRenderEffectImpl& impl3 =
-    *(dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control1.GetRenderEffect().GetObjectPtr()));
+  Toolkit::Internal::TestRenderEffectImplPtr impl3 =
+    dynamic_cast<Toolkit::Internal::TestRenderEffectImpl*>(control1.GetRenderEffect().GetObjectPtr());
 
-  DALI_TEST_EQUALS(&impl1 == &impl3, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.IsActivated(), false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.mOnActivated, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl1.GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1 == impl3, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->mOnActivated, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl1->GetOwnerControl(), Toolkit::Control(), TEST_LOCATION);
 
-  DALI_TEST_EQUALS(impl3.IsActivated(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl3.mOnActivated, true, TEST_LOCATION);
-  DALI_TEST_EQUALS(impl3.GetOwnerControl(), control1, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl3->mOnActivated, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(impl3->GetOwnerControl(), control1, TEST_LOCATION);
 
   tet_printf("Test control1 call SetRenderEffect with empty handle\n");
   control1.SetRenderEffect(Toolkit::RenderEffect());
index 52c7e0fb26a1dbf224d11739111305462c3b1a69..5f4293346b3f9c653377063dc502204c6c37687d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1500,20 +1500,27 @@ int UtcDaliControlOffScreenRendering(void)
   Control control = Control::New();
   control.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
   control.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
   application.GetScene().Add(control);
+
   control.SetBackgroundColor(Color::RED);
   DALI_TEST_EQUALS(control.GetProperty(DevelControl::Property::OFFSCREEN_RENDERING).Get<int>(), (int)DevelControl::OffScreenRenderingType::NONE, TEST_LOCATION);
+  tet_infoline("Control is ready");
 
   control.SetProperty(DevelControl::Property::OFFSCREEN_RENDERING, DevelControl::OffScreenRenderingType::REFRESH_ALWAYS);
   DALI_TEST_EQUALS(control.GetProperty(DevelControl::Property::OFFSCREEN_RENDERING).Get<int>(), (int)DevelControl::OffScreenRenderingType::REFRESH_ALWAYS, TEST_LOCATION);
+  tet_infoline("Set offscreen rendering : refresh always");
+
   control.SetProperty(DevelControl::Property::OFFSCREEN_RENDERING, DevelControl::OffScreenRenderingType::REFRESH_ONCE);
   DALI_TEST_EQUALS(control.GetProperty(DevelControl::Property::OFFSCREEN_RENDERING).Get<int>(), (int)DevelControl::OffScreenRenderingType::REFRESH_ONCE, TEST_LOCATION);
+  tet_infoline("Set offscreen rendering : refresh once");
 
   application.SendNotification();
   application.Render();
 
   control.SetProperty(DevelControl::Property::OFFSCREEN_RENDERING, DevelControl::OffScreenRenderingType::NONE);
   DALI_TEST_EQUALS(control.GetProperty(DevelControl::Property::OFFSCREEN_RENDERING).Get<int>(), (int)DevelControl::OffScreenRenderingType::NONE, TEST_LOCATION);
+  tet_infoline("Turn off offscreen rendering");
 
   control.Unparent(); // Disconnect fron scene.
   application.GetScene().Add(control);
index 326f90ea8a15379f11da4805598be6b409a9b511..89731c07b25ccb367fbf5096a6c5335d5be04bbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -403,7 +403,7 @@ Control::Impl::Impl(Control& controlImpl)
   mPanGestureDetector(),
   mTapGestureDetector(),
   mLongPressGestureDetector(),
-  mOffScreenRenderingContext(nullptr),
+  mOffScreenRenderingImpl(nullptr),
   mOffScreenRenderingType(DevelControl::OffScreenRenderingType::NONE),
   mTooltip(NULL),
   mInputMethodContext(),
@@ -537,9 +537,9 @@ void Control::Impl::OnSceneConnection()
     }
   }
 
-  if(mOffScreenRenderingContext) // mOffScreenRenderingType != NONE
+  if(mOffScreenRenderingImpl) // mOffScreenRenderingType != NONE
   {
-    mOffScreenRenderingContext->Enable(Toolkit::Control(mControlImpl.GetOwner()), mOffScreenRenderingType);
+    mOffScreenRenderingImpl->SetOwnerControl(Toolkit::Control(mControlImpl.GetOwner()));
   }
 }
 
@@ -548,9 +548,9 @@ void Control::Impl::OnSceneDisconnection()
   Actor self = mControlImpl.Self();
   mVisualData->ClearScene(self);
 
-  if(mOffScreenRenderingContext)
+  if(mOffScreenRenderingImpl)
   {
-    mOffScreenRenderingContext->Disable(Toolkit::Control(mControlImpl.GetOwner()));
+    mOffScreenRenderingImpl->ClearOwnerControl();
   }
 }
 
@@ -1557,31 +1557,22 @@ void Control::Impl::SetOffScreenRendering(int32_t offScreenRenderingType)
     }
   }
 
-  mOffScreenRenderingType = static_cast<DevelControl::OffScreenRenderingType>(offScreenRenderingType);
-  Dali::Toolkit::Control handle(mControlImpl.GetOwner());
-
-  // Disable
-  if(mOffScreenRenderingType == DevelControl::OffScreenRenderingType::NONE)
-  {
-    if(mOffScreenRenderingContext)
-    {
-      mOffScreenRenderingContext->Disable(handle);
-      mOffScreenRenderingContext.reset();
-    }
-  }
-  // Enable
-  else
+  DevelControl::OffScreenRenderingType newType = static_cast<DevelControl::OffScreenRenderingType>(offScreenRenderingType);
+  if(newType != mOffScreenRenderingType)
   {
-    if(mOffScreenRenderingContext)
-    {
-      mOffScreenRenderingContext->Disable(handle);
-    }
-    else
+    // update type
+    mOffScreenRenderingType = newType;
+
+    // update effect
+    if(mOffScreenRenderingImpl)
     {
-      Dali::Toolkit::Control handle(mControlImpl.GetOwner());
-      mOffScreenRenderingContext = std::make_unique<OffScreenRenderingContext>();
+      mOffScreenRenderingImpl->ClearOwnerControl();
+      mOffScreenRenderingImpl.reset();
     }
-    mOffScreenRenderingContext->Enable(handle, mOffScreenRenderingType);
+    mOffScreenRenderingImpl = std::make_unique<OffScreenRenderingImpl>(mOffScreenRenderingType);
+
+    Dali::Toolkit::Control handle(mControlImpl.GetOwner());
+    mOffScreenRenderingImpl->SetOwnerControl(handle);
   }
 }
 
index 8248a5cd3df0705ca1e730ca70e082cb2985b0b9..4232a827273cc64ad67fc24fee74474cf1a14f58 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_CONTROL_DATA_IMPL_H
 
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.h>
+#include <dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.h>
 #include <dali-toolkit/internal/controls/render-effects/render-effect-impl.h>
 #include <dali-toolkit/internal/controls/tooltip/tooltip.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
@@ -496,8 +496,8 @@ public:
   LongPressGestureDetector mLongPressGestureDetector;
 
   // Off screen rendering context
-  std::unique_ptr<OffScreenRenderingContext> mOffScreenRenderingContext;
-  DevelControl::OffScreenRenderingType       mOffScreenRenderingType;
+  std::unique_ptr<OffScreenRenderingImpl> mOffScreenRenderingImpl;
+  DevelControl::OffScreenRenderingType    mOffScreenRenderingType;
 
   // Tooltip
   TooltipPtr mTooltip;
index b7ea03f201be7530c456ba350351b60bfce95cc8..c39aec040fa677a88162fcc9c995553d3ad63bd5 100644 (file)
@@ -20,7 +20,6 @@
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/actors/custom-actor-impl.h>
 #include <dali/public-api/images/image-operations.h>
@@ -30,7 +29,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/controls/control/control-renderers.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
@@ -186,13 +184,6 @@ void BlurEffectImpl::OnInitialize()
 
   // Create CameraActors
   {
-    mRenderFullSizeCamera = CameraActor::New();
-    mRenderFullSizeCamera.SetInvertYAxis(true);
-    mRenderFullSizeCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-    mRenderFullSizeCamera.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
-    mRenderFullSizeCamera.SetType(Dali::Camera::FREE_LOOK);
-    mInternalRoot.Add(mRenderFullSizeCamera);
-
     mRenderDownsampledCamera = CameraActor::New();
     mRenderDownsampledCamera.SetInvertYAxis(true);
     mRenderDownsampledCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
@@ -265,35 +256,21 @@ void BlurEffectImpl::OnActivate()
   DALI_ASSERT_ALWAYS(ownerControl && "Set the owner of RenderEffect before you activate.");
 
   // Get size
-  Vector2 size = GetTargetSizeForValidTexture();
+  Vector2 size = GetTargetSize();
   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;
-  }
   uint32_t downsampledWidth  = std::max(static_cast<uint32_t>(size.width * mDownscaleFactor), 1u);
   uint32_t downsampledHeight = std::max(static_cast<uint32_t>(size.height * mDownscaleFactor), 1u);
 
   // Set size
-  mRenderFullSizeCamera.SetPerspectiveProjection(size);
   mRenderDownsampledCamera.SetPerspectiveProjection(Size(downsampledWidth, downsampledHeight));
 
   mHorizontalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight));
   mVerticalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight));
 
-  // Keep sceneHolder as weak handle.
-  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;
-  }
-  mPlacementSceneHolder = sceneHolder;
-
   // Set blur
   CreateFrameBuffers(size, ImageDimensions(downsampledWidth, downsampledHeight));
-  CreateRenderTasks(sceneHolder, ownerControl);
+  CreateRenderTasks(GetSceneHolder(), ownerControl);
   SetShaderConstants(downsampledWidth, downsampledHeight);
 
   // Inject blurred output to control
@@ -337,14 +314,13 @@ void BlurEffectImpl::OnDeactivate()
   mTemporaryFrameBuffer.Reset();
   mSourceFrameBuffer.Reset();
 
-  auto sceneHolder = mPlacementSceneHolder.GetHandle();
+  auto sceneHolder = GetSceneHolder();
   if(DALI_LIKELY(sceneHolder))
   {
     RenderTaskList taskList = sceneHolder.GetRenderTaskList();
     taskList.RemoveTask(mHorizontalBlurTask);
     taskList.RemoveTask(mVerticalBlurTask);
     taskList.RemoveTask(mSourceRenderTask);
-    mPlacementSceneHolder.Reset();
   }
 
   mHorizontalBlurTask.Reset();
@@ -379,7 +355,7 @@ void BlurEffectImpl::CreateRenderTasks(Integration::SceneHolder sceneHolder, con
 
   // draw input texture
   mSourceRenderTask = taskList.CreateTask();
-  mSourceRenderTask.SetCameraActor(mRenderFullSizeCamera);
+  mSourceRenderTask.SetCameraActor(GetCameraActor());
   mSourceRenderTask.SetFrameBuffer(mInputBackgroundFrameBuffer);
   mSourceRenderTask.SetInputEnabled(false);
 
@@ -448,29 +424,6 @@ void BlurEffectImpl::ApplyRenderTaskSourceActor(RenderTask sourceRenderTask, con
   sourceRenderTask.RenderUntil(stopperActor);
 }
 
-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(uint32_t downsampledWidth, uint32_t downsampledHeight)
 {
   const uint32_t sampleCount    = mPixelRadius >> 1; // compression
@@ -514,12 +467,6 @@ void BlurEffectImpl::SetShaderConstants(uint32_t downsampledWidth, uint32_t down
     mVerticalBlurActor.RegisterProperty(GetSampleOffsetsPropertyName(i), Vector2(0.0f, uvOffsets[i] / downsampledHeight));
     mVerticalBlurActor.RegisterProperty(GetSampleWeightsPropertyName(i), weights[i]);
   }
-
-  // Apply background properties
-  if(mIsBackground)
-  {
-    SynchronizeBackgroundCornerRadius();
-  }
 }
 
 std::string BlurEffectImpl::GetSampleOffsetsPropertyName(unsigned int index) const
@@ -536,29 +483,6 @@ std::string BlurEffectImpl::GetSampleWeightsPropertyName(unsigned int index) con
   return oss.str();
 }
 
-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);
-
-  Vector4 squareness = Vector4::ZERO;
-  map[Toolkit::DevelVisual::Property::CORNER_SQUARENESS].Get(squareness);
-
-  Visual::Transform::Policy::Type policy{Visual::Transform::Policy::ABSOLUTE};
-  map[Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY].Get(policy);
-
-  Renderer renderer = GetTargetRenderer();
-  renderer.RegisterProperty("uCornerRadius", radius);
-  renderer.RegisterProperty("uCornerSquareness", squareness);
-  renderer.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(policy));
-}
-
 } // namespace Internal
 } // namespace Toolkit
 } // namespace Dali
index e24f3521765f145ecb9c5e9a79650265bb378d32..c60ce241ac613e7d45fa00e2de536ee824f5fdc8 100644 (file)
@@ -142,14 +142,6 @@ private:
    */
   void ApplyRenderTaskSourceActor(RenderTask sourceRenderTask, const Toolkit::Control sourceControl);
 
-  /**
-   * @brief Gets or Calculates a valid target size for texture.
-   * Invalid cases include: zero vector, minus numbers or large numbers(larger than the maximum).
-   * @return A valid version of mTargetSize, Vector2::ZERO otherwise.
-   * @note The return value is a copy, not mTargetSize itself.
-   */
-  Vector2 GetTargetSizeForValidTexture() const;
-
   /**
    * @brief Sets shader constants, gaussian kernel weights and pixel offsets.
    * @param[in] downsampledWidth Downsized width of input texture.
@@ -171,11 +163,6 @@ private:
    */
   std::string GetSampleWeightsPropertyName(unsigned int index) const;
 
-  /**
-   * @brief Synchronize mOwnerControl's background corner radius to the blurred output.
-   */
-  void SynchronizeBackgroundCornerRadius();
-
   BlurEffectImpl(const BlurEffectImpl&) = delete;
   BlurEffectImpl(BlurEffectImpl&&)      = delete;
   BlurEffectImpl& operator=(BlurEffectImpl&&) = delete;      // no move()
@@ -183,14 +170,11 @@ private:
 
 private:
   // Camera actors
-  CameraActor mRenderFullSizeCamera;
   CameraActor mRenderDownsampledCamera;
 
   // Resource
   FrameBuffer mInputBackgroundFrameBuffer; // Input. Background. What to blur.
 
-  WeakHandle<Integration::SceneHolder> mPlacementSceneHolder;
-
   Actor       mInternalRoot;
   Actor       mHorizontalBlurActor;
   RenderTask  mHorizontalBlurTask;
diff --git a/dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.cpp b/dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.cpp
deleted file mode 100644 (file)
index a057add..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/control/control-renderers.h>
-#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
-
-// EXTERNAL INCLUDES
-#include <integration-api/debug.h>
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Internal
-{
-bool OffScreenRenderingContext::IsEnabled()
-{
-  return mCamera && mRenderer;
-}
-
-void OffScreenRenderingContext::Enable(Toolkit::Control control, DevelControl::OffScreenRenderingType type)
-{
-  if(type == DevelControl::OffScreenRenderingType::NONE)
-  {
-    return;
-  }
-
-  // Create resources
-  if(!IsEnabled())
-  {
-    Integration::SceneHolder sceneHolder = Integration::SceneHolder::Get(control);
-    if(DALI_UNLIKELY(!sceneHolder))
-    {
-      DALI_LOG_ERROR("Could not enable offscreen rendering. The control is not connected to a scene.\n");
-      return;
-    }
-    mSceneHolder = sceneHolder;
-
-    const Size size = control.GetProperty<Size>(Actor::Property::SIZE);
-
-    mCamera = CameraActor::New(size);
-    mCamera.SetInvertYAxis(true);
-    mCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-    mCamera.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
-    mCamera.SetType(Camera::FREE_LOOK);
-    mCamera.SetPerspectiveProjection(size);
-    control.Add(mCamera);
-
-    mFrameBuffer    = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
-    Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, size.width, size.height);
-    mFrameBuffer.AttachColorTexture(texture);
-
-    RenderTaskList taskList = sceneHolder.GetRenderTaskList();
-    mRenderTask             = taskList.CreateTask();
-    mRenderTask.SetSourceActor(control);
-    mRenderTask.SetCameraActor(mCamera);
-    mRenderTask.SetExclusive(true);
-    mRenderTask.SetInputEnabled(false);
-    mRenderTask.SetFrameBuffer(mFrameBuffer);
-    mRenderTask.SetClearEnabled(true);
-    mRenderTask.SetClearColor(sceneHolder.GetBackgroundColor());
-
-    mRenderer = CreateRenderer(SHADER_CONTROL_RENDERERS_VERT, SHADER_CONTROL_RENDERERS_FRAG);
-    SetRendererTexture(mRenderer, mFrameBuffer);
-
-    control.GetImplementation().SetCacheRenderer(mRenderer);
-    control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::FORWARD);
-  }
-
-  // Set refresh rate
-  if(type == DevelControl::OffScreenRenderingType::REFRESH_ALWAYS)
-  {
-    mRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
-  }
-  else if(type == DevelControl::OffScreenRenderingType::REFRESH_ONCE)
-  {
-    mRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
-  }
-}
-
-void OffScreenRenderingContext::Disable(Toolkit::Control control)
-{
-  if(IsEnabled())
-  {
-    if(DALI_LIKELY(control))
-    {
-      control.GetImplementation().RemoveCacheRenderer();
-
-      mCamera.Unparent();
-      control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::NONE);
-    }
-
-    auto sceneHolder = mSceneHolder.GetHandle();
-    if(DALI_LIKELY(sceneHolder))
-    {
-      RenderTaskList taskList = sceneHolder.GetRenderTaskList();
-      taskList.RemoveTask(mRenderTask);
-    }
-    mSceneHolder.Reset();
-
-    mFrameBuffer.Reset();
-    mRenderTask.Reset();
-    mCamera.Reset();
-    mRenderer.Reset();
-  }
-}
-
-} // namespace Internal
-} // namespace Toolkit
-} // namespace Dali
diff --git a/dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.h b/dali-toolkit/internal/controls/render-effects/offscreen-rendering-context.h
deleted file mode 100644 (file)
index 6299d12..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_CONTEXT
-#define DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_CONTEXT
-
-/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// 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-list.h>
-#include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/rendering/frame-buffer.h>
-#include <dali/public-api/rendering/renderer.h>
-#include <integration-api/adaptor-framework/scene-holder.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/public-api/controls/control.h>
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Internal
-{
-class OffScreenRenderingContext
-{
-public:
-  OffScreenRenderingContext() = default;
-  void Enable(Toolkit::Control control, DevelControl::OffScreenRenderingType type);
-  void Disable(Toolkit::Control control);
-
-private:
-  bool IsEnabled();
-
-private:
-  RenderTask  mRenderTask;
-  CameraActor mCamera;
-  FrameBuffer mFrameBuffer;
-  Renderer    mRenderer;
-
-  WeakHandle<Integration::SceneHolder> mSceneHolder;
-};
-} // namespace Internal
-} // namespace Toolkit
-} // namespace Dali
-#endif //DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_CONTEXT
diff --git a/dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.cpp b/dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.cpp
new file mode 100644 (file)
index 0000000..58b12c0
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/control/control-renderers.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+
+// EXTERNAL INCLUDES
+#include <integration-api/debug.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+OffScreenRenderingImpl::OffScreenRenderingImpl(DevelControl::OffScreenRenderingType type)
+: mType(type)
+{
+  Initialize();
+}
+
+RenderEffectImplPtr OffScreenRenderingImpl::Clone() const
+{
+  DALI_LOG_ERROR("Cloning offscreen rendering is not allowed.\n");
+  return RenderEffectImplPtr();
+}
+
+OffScreenRenderable::Type OffScreenRenderingImpl::GetOffScreenRenderableType()
+{
+  return OffScreenRenderable::Type::FORWARD;
+}
+
+void OffScreenRenderingImpl::GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward)
+{
+}
+
+void OffScreenRenderingImpl::OnInitialize()
+{
+}
+
+void OffScreenRenderingImpl::OnActivate()
+{
+  if(mType == DevelControl::OffScreenRenderingType::NONE)
+  {
+    return;
+  }
+
+  // Create resources
+  Toolkit::Control control = GetOwnerControl();
+  const Size       size    = GetTargetSize();
+
+  mFrameBuffer    = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
+  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, size.width, size.height);
+  mFrameBuffer.AttachColorTexture(texture);
+
+  Integration::SceneHolder sceneHolder = GetSceneHolder();
+  RenderTaskList           taskList    = sceneHolder.GetRenderTaskList();
+  mRenderTask                          = taskList.CreateTask();
+  mRenderTask.SetSourceActor(control);
+  mRenderTask.SetCameraActor(GetCameraActor());
+  mRenderTask.SetExclusive(true);
+  mRenderTask.SetInputEnabled(false);
+  mRenderTask.SetFrameBuffer(mFrameBuffer);
+  mRenderTask.SetClearEnabled(true);
+  mRenderTask.SetClearColor(sceneHolder.GetBackgroundColor());
+
+  Renderer renderer = GetTargetRenderer();
+  SetRendererTexture(renderer, mFrameBuffer);
+
+  control.GetImplementation().SetCacheRenderer(renderer);
+  control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::FORWARD);
+
+  // Set refresh rate
+  if(mType == DevelControl::OffScreenRenderingType::REFRESH_ALWAYS)
+  {
+    mRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
+  }
+  else if(mType == DevelControl::OffScreenRenderingType::REFRESH_ONCE)
+  {
+    mRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
+  }
+}
+
+void OffScreenRenderingImpl::OnDeactivate()
+{
+  Toolkit::Control control = GetOwnerControl();
+  if(DALI_LIKELY(control))
+  {
+    control.GetImplementation().RemoveCacheRenderer();
+    control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::NONE);
+  }
+
+  auto sceneHolder = GetSceneHolder();
+  if(DALI_LIKELY(sceneHolder))
+  {
+    RenderTaskList taskList = sceneHolder.GetRenderTaskList();
+    taskList.RemoveTask(mRenderTask);
+  }
+
+  mFrameBuffer.Reset();
+  mRenderTask.Reset();
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.h b/dali-toolkit/internal/controls/render-effects/offscreen-rendering-impl.h
new file mode 100644 (file)
index 0000000..16034d7
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_IMPL
+#define DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_IMPL
+
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// 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-list.h>
+#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/rendering/frame-buffer.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <integration-api/adaptor-framework/scene-holder.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/render-effects/render-effect-impl.h>
+#include <dali-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+class OffScreenRenderingImpl : public RenderEffectImpl
+{
+public:
+  OffScreenRenderingImpl(DevelControl::OffScreenRenderingType type);
+  RenderEffectImplPtr       Clone() const override;
+  OffScreenRenderable::Type GetOffScreenRenderableType() override;
+  void                      GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override;
+
+protected:
+  void OnInitialize() override;
+  void OnActivate() override;
+  void OnDeactivate() override;
+
+private:
+  RenderTask                           mRenderTask;
+  FrameBuffer                          mFrameBuffer;
+  DevelControl::OffScreenRenderingType mType;
+};
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
+#endif //DALI_TOOLKIT_INTERNAL_OFFSCREEN_RENDERING_IMPL
index 633ce3fba7ef23a0e7f718b2962870cb9497b6fa..3533062e4b3f47365dd631b20de23c5e5cc34652 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali-toolkit/internal/controls/render-effects/render-effect-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/integration-api/adaptor-framework/scene-holder.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/controls/control/control-renderers.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 
@@ -44,6 +46,7 @@ Debug::Filter* gRenderEffectLogFilter = Debug::Filter::New(Debug::NoLogging, fal
 
 RenderEffectImpl::RenderEffectImpl()
 : mRenderer(),
+  mCamera(),
   mOwnerControl(),
   mSizeNotification(),
   mTargetSize(Vector2::ZERO),
@@ -58,6 +61,9 @@ RenderEffectImpl::~RenderEffectImpl()
 
   // Reset weak handle first. (Since it might not valid during destruction.)
   mOwnerControl.Reset();
+  mPlacementSceneHolder.Reset();
+
+  mSizeNotification.Reset();
 
   // Don't call Deactivate here, since we cannot call virtual function during destruction.
   // Deactivate already be called at Control's destructor, and InheritVisibilityChanged signal.
@@ -77,17 +83,7 @@ void RenderEffectImpl::SetOwnerControl(Dali::Toolkit::Control control)
 
     if(ownerControl)
     {
-      mTargetSize = ownerControl.GetProperty<Vector2>(Actor::Property::SIZE);
-      if(!mRenderer)
-      {
-        mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG);
-        mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); // Always use pre-multiply alpha
-
-        Shader shader = mRenderer.GetShader();
-        shader.RegisterProperty("uCornerRadius", Vector4::ZERO);
-        shader.RegisterProperty("uCornerSquareness", Vector4::ZERO);
-        shader.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(1.0f));
-      }
+      UpdateTargetSize();
 
       ownerControl.InheritedVisibilityChangedSignal().Connect(this, &RenderEffectImpl::OnControlInheritedVisibilityChanged);
 
@@ -114,6 +110,7 @@ void RenderEffectImpl::ClearOwnerControl()
 
     auto previousOwnerControl = ownerControl;
     mOwnerControl.Reset();
+    mPlacementSceneHolder.Reset();
 
     // Make previous owner don't have render effect, after make we don't have owner control now.
     previousOwnerControl.ClearRenderEffect();
@@ -127,6 +124,12 @@ bool RenderEffectImpl::IsActivated() const
 
 void RenderEffectImpl::Initialize()
 {
+  mCamera = CameraActor::New();
+  mCamera.SetInvertYAxis(true);
+  mCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  mCamera.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  mCamera.SetType(Dali::Camera::FREE_LOOK);
+
   OnInitialize();
 }
 
@@ -135,6 +138,11 @@ Toolkit::Control RenderEffectImpl::GetOwnerControl() const
   return mOwnerControl.GetHandle();
 }
 
+Integration::SceneHolder RenderEffectImpl::GetSceneHolder() const
+{
+  return mPlacementSceneHolder.GetHandle();
+}
+
 Renderer RenderEffectImpl::GetTargetRenderer() const
 {
   return mRenderer;
@@ -145,16 +153,51 @@ Vector2 RenderEffectImpl::GetTargetSize() const
   return mTargetSize;
 }
 
+CameraActor RenderEffectImpl::GetCameraActor() const
+{
+  return mCamera;
+}
+
 void RenderEffectImpl::Activate()
 {
   if(!IsActivated() && IsActivateValid())
   {
+    mIsActivated = true;
+
     Dali::Toolkit::Control ownerControl = mOwnerControl.GetHandle();
     DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] Activated! [ID:%d]\n", this, ownerControl ? ownerControl.GetProperty<int>(Actor::Property::ID) : -1);
-    mIsActivated = true;
 
-    // Activate logic for subclass.
-    OnActivate();
+    // Keep sceneHolder as weak handle.
+    Integration::SceneHolder sceneHolder = Integration::SceneHolder::Get(ownerControl);
+    if(DALI_UNLIKELY(!sceneHolder))
+    {
+      DALI_LOG_ERROR("RenderEffect Could not be activated due to ownerControl's SceneHolder is not exist\n");
+      return;
+    }
+    mPlacementSceneHolder = sceneHolder;
+
+    if(!mRenderer)
+    {
+      mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG);
+      mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); // Always use pre-multiply alpha
+
+      Shader shader = mRenderer.GetShader();
+      shader.RegisterProperty("uCornerRadius", Vector4::ZERO);
+      shader.RegisterProperty("uCornerSquareness", Vector4::ZERO);
+      shader.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(1.0f));
+    }
+
+    Vector2 size = GetTargetSize();
+    if(size != Vector2::ZERO)
+    {
+      mCamera.SetPerspectiveProjection(size);
+      ownerControl.Add(mCamera);
+
+      // Activate logic for subclass.
+      OnActivate();
+
+      SynchronizeBackgroundCornerRadius();
+    }
   }
 }
 
@@ -162,12 +205,15 @@ void RenderEffectImpl::Deactivate()
 {
   if(IsActivated() || !IsActivateValid())
   {
+    mIsActivated = false;
+
     Dali::Toolkit::Control ownerControl = mOwnerControl.GetHandle();
     DALI_LOG_INFO(gRenderEffectLogFilter, Debug::General, "[RenderEffect:%p] Deactivated! [ID:%d]\n", this, ownerControl ? ownerControl.GetProperty<int>(Actor::Property::ID) : -1);
-    mIsActivated = false;
 
     // Deactivate logic for subclass.
     OnDeactivate();
+
+    mCamera.Unparent();
   }
 }
 
@@ -209,6 +255,29 @@ bool RenderEffectImpl::IsActivateValid() const
   return ret;
 }
 
+void RenderEffectImpl::UpdateTargetSize()
+{
+  Vector2 size = GetOwnerControl().GetProperty<Vector2>(Actor::Property::SIZE);
+  if(size == Vector2::ZERO)
+  {
+    size = GetOwnerControl().GetNaturalSize();
+  }
+
+  if(size == Vector2::ZERO || size.x < 0.0f || size.y < 0.0f)
+  {
+    mTargetSize = 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);
+  }
+  mTargetSize = size;
+}
+
 void RenderEffectImpl::OnSizeSet(PropertyNotification& source)
 {
   Dali::Toolkit::Control ownerControl = mOwnerControl.GetHandle();
@@ -217,7 +286,7 @@ void RenderEffectImpl::OnSizeSet(PropertyNotification& source)
     const auto targetSize = ownerControl.GetCurrentProperty<Vector2>(Actor::Property::SIZE);
     if(mTargetSize != targetSize && IsActivated())
     {
-      mTargetSize = targetSize;
+      UpdateTargetSize();
       Deactivate();
       Activate();
     }
@@ -238,6 +307,29 @@ void RenderEffectImpl::OnControlInheritedVisibilityChanged(Actor actor, bool vis
   }
 }
 
+void RenderEffectImpl::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);
+
+  Vector4 squareness = Vector4::ZERO;
+  map[Toolkit::DevelVisual::Property::CORNER_SQUARENESS].Get(squareness);
+
+  Visual::Transform::Policy::Type policy{Visual::Transform::Policy::ABSOLUTE};
+  map[Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY].Get(policy);
+
+  Renderer renderer = GetTargetRenderer();
+  renderer.RegisterProperty("uCornerRadius", radius);
+  renderer.RegisterProperty("uCornerSquareness", squareness);
+  renderer.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(policy));
+}
+
 } // namespace Internal
 } // namespace Toolkit
 } // namespace Dali
index 07e805544e7338825ee9bf6fb464a4976a733bb9..67f72070d2faa2ee67e3bcb1498b6cfd73dcf0a0 100644 (file)
@@ -19,6 +19,8 @@
  */
 
 // EXTERNAL INCLUDE
+#include <dali/integration-api/adaptor-framework/scene-holder.h>
+#include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/object/base-object.h>
@@ -54,12 +56,6 @@ public:
    */
   void ClearOwnerControl();
 
-  /**
-   * @brief Get whether this effect activated or not.
-   * @return True if effect is activated. False otherwise.
-   */
-  bool IsActivated() const;
-
   /**
    * @brief Clones current instance.
    * @return Clone implementation
@@ -123,12 +119,24 @@ protected:
    */
   Vector2 GetTargetSize() const;
 
+  /**
+   * @brief Get camera that captures full size texture of mOwnerControl
+   * @return mCamera
+   */
+  CameraActor GetCameraActor() const;
+
   /**
    * @brief Get Owner control. It could be return empty handle if owner control is not set, or destroyed.
    * @return mOwnerControl
    */
   Toolkit::Control GetOwnerControl() const;
 
+  /**
+   * @brief Get scene holder of owner control.
+   * @return mPlacementSceneHolder
+   */
+  Integration::SceneHolder GetSceneHolder() const;
+
   /// For sub classes
 protected:
   /**
@@ -164,7 +172,19 @@ private:
    */
   bool IsActivateValid() const;
 
+  /**
+   * @brief Get whether this effect activated or not.
+   * @return True if effect is activated. False otherwise.
+   */
+  bool IsActivated() const;
+
 private:
+  /**
+   * @brief Calculates a valid target size for texture.
+   * Invalid cases include: zero vector, minus numbers or large numbers(larger than the maximum).
+   */
+  void UpdateTargetSize();
+
   /**
    * @brief Callback when the size changes.
    */
@@ -177,10 +197,17 @@ private:
    */
   void OnControlInheritedVisibilityChanged(Actor actor, bool visible);
 
+  /**
+   * @brief Synchronize mOwnerControl's background corner radius to the output.
+   */
+  void SynchronizeBackgroundCornerRadius();
+
 private:
   Dali::Renderer mRenderer; // An additional renderer for mOwnerControl
+  CameraActor    mCamera;   // A camera that captures full size texture of mOwnerControl
 
-  Dali::WeakHandle<Dali::Toolkit::Control> mOwnerControl; ///< Weakhandle of owner control.
+  Dali::WeakHandle<Dali::Toolkit::Control> mOwnerControl;         ///< Weakhandle of owner control.
+  WeakHandle<Integration::SceneHolder>     mPlacementSceneHolder; ///< Weakhandle of scene
 
   PropertyNotification mSizeNotification; // Resize/Relayout signal.
   Vector2              mTargetSize;       // The final size of mOwnerControl
index 12d902d03177de82f2e29d027f6f5edcd5691d41..6cc4e5f5c6e7fb240cb05e5a36b8460c09a062fb 100644 (file)
@@ -71,7 +71,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/alignment/alignment-impl.cpp
    ${toolkit_src_dir}/controls/render-effects/render-effect-impl.cpp
    ${toolkit_src_dir}/controls/render-effects/blur-effect-impl.cpp
-   ${toolkit_src_dir}/controls/render-effects/offscreen-rendering-context.cpp
+   ${toolkit_src_dir}/controls/render-effects/offscreen-rendering-impl.cpp
    ${toolkit_src_dir}/controls/bloom-view/bloom-view-impl.cpp
    ${toolkit_src_dir}/controls/bubble-effect/bubble-emitter-impl.cpp
    ${toolkit_src_dir}/controls/bubble-effect/bubble-renderer.cpp
index cce28774516dcada7668f066552bd95e7c81d885..8cf3cbc23028caa8b1b60de42d626e102524dd71 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_RENDER_EFFECT_H
 
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-handle.h>
 #include <dali/public-api/render-tasks/render-task.h>
-#include <memory> // std::shared_ptr
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>