// 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);
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;
// 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());
/*
- * 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.
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);
/*
- * 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.
mPanGestureDetector(),
mTapGestureDetector(),
mLongPressGestureDetector(),
- mOffScreenRenderingContext(nullptr),
+ mOffScreenRenderingImpl(nullptr),
mOffScreenRenderingType(DevelControl::OffScreenRenderingType::NONE),
mTooltip(NULL),
mInputMethodContext(),
}
}
- if(mOffScreenRenderingContext) // mOffScreenRenderingType != NONE
+ if(mOffScreenRenderingImpl) // mOffScreenRenderingType != NONE
{
- mOffScreenRenderingContext->Enable(Toolkit::Control(mControlImpl.GetOwner()), mOffScreenRenderingType);
+ mOffScreenRenderingImpl->SetOwnerControl(Toolkit::Control(mControlImpl.GetOwner()));
}
}
Actor self = mControlImpl.Self();
mVisualData->ClearScene(self);
- if(mOffScreenRenderingContext)
+ if(mOffScreenRenderingImpl)
{
- mOffScreenRenderingContext->Disable(Toolkit::Control(mControlImpl.GetOwner()));
+ mOffScreenRenderingImpl->ClearOwnerControl();
}
}
}
}
- 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);
}
}
#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.
// 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>
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;
// 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>
// 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>
// 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);
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
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();
// draw input texture
mSourceRenderTask = taskList.CreateTask();
- mSourceRenderTask.SetCameraActor(mRenderFullSizeCamera);
+ mSourceRenderTask.SetCameraActor(GetCameraActor());
mSourceRenderTask.SetFrameBuffer(mInputBackgroundFrameBuffer);
mSourceRenderTask.SetInputEnabled(false);
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
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
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
*/
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.
*/
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()
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;
+++ /dev/null
-/*
- * 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
+++ /dev/null
-#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
/*
- * 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>
RenderEffectImpl::RenderEffectImpl()
: mRenderer(),
+ mCamera(),
mOwnerControl(),
mSizeNotification(),
mTargetSize(Vector2::ZERO),
// 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.
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);
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();
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();
}
return mOwnerControl.GetHandle();
}
+Integration::SceneHolder RenderEffectImpl::GetSceneHolder() const
+{
+ return mPlacementSceneHolder.GetHandle();
+}
+
Renderer RenderEffectImpl::GetTargetRenderer() const
{
return mRenderer;
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();
+ }
}
}
{
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();
}
}
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();
const auto targetSize = ownerControl.GetCurrentProperty<Vector2>(Actor::Property::SIZE);
if(mTargetSize != targetSize && IsActivated())
{
- mTargetSize = targetSize;
+ UpdateTargetSize();
Deactivate();
Activate();
}
}
}
+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
*/
// 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>
*/
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
*/
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:
/**
*/
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.
*/
*/
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
${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
#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.
// 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>