From: jmm Date: Fri, 12 Apr 2024 04:35:02 +0000 (+0900) Subject: Support RenderEffect X-Git-Tag: dali_2.3.29~13^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F09%2F309609%2F42;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Support RenderEffect Change-Id: I9c302358dd984906bf26dc7423c9ce7f02de0f8e --- diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 8d33504..75f2eb6 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -11,6 +11,7 @@ SET(TC_SOURCES utc-Dali-AnimatedImageVisual.cpp utc-Dali-AnimatedVectorImageVisual.cpp utc-Dali-ArcVisual.cpp + utc-Dali-RenderEffect.cpp utc-Dali-BloomView.cpp utc-Dali-BubbleEmitter.cpp utc-Dali-Builder.cpp diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp new file mode 100644 index 0000000..5f1933b --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp @@ -0,0 +1,191 @@ +/* + * 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. + * + */ + +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +int UtcDaliRenderEffectNewP(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectNewP"); + + BackgroundBlurEffect blurEffect = BackgroundBlurEffect::New(); + DALI_TEST_CHECK(blurEffect); + + BackgroundBlurEffect blurEffect2 = BackgroundBlurEffect::New(0.5f, 10.0f, 10.0f); + DALI_TEST_CHECK(blurEffect2); + + END_TEST; +} + +int UtcDaliRenderEffectNewN(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectNewN"); + + try + { + BackgroundBlurEffect blurEffect = BackgroundBlurEffect::New(-0.5f, 10.0f, 10.0f); + BackgroundBlurEffect blurEffect2 = BackgroundBlurEffect::New(10.0f, 10.0f, 10.0f); + DALI_TEST_CHECK(!blurEffect && !blurEffect2); + } + catch(Dali::DaliException& e) + { + DALI_TEST_PRINT_ASSERT(e); + DALI_TEST_CHECK(true); + } + END_TEST; +} + +int UtcDaliRenderEffectActivateP01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectActivateP01"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + Control childControl = Control::New(); + childControl.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + + scene.Add(control); + control.Add(childControl); + + RenderTaskList taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(1u == taskList.GetTaskCount()); + + childControl.SetRenderEffect(BackgroundBlurEffect::New()); + + taskList = scene.GetRenderTaskList(); + DALI_LOG_ERROR("%d\n", taskList.GetTaskCount()); + DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + + END_TEST; +} + +int UtcDaliRenderEffectActivateP02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectActivateP02"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + scene.Add(control); + + BackgroundBlurEffect blurEffect = BackgroundBlurEffect::New(); + control.SetRenderEffect(blurEffect); + + RenderTaskList taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + + Control control2 = Control::New(); + control2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control2.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + scene.Add(control2); + + control2.SetRenderEffect(blurEffect); // Ownership changed. + taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + + END_TEST; +} + +int UtcDaliRenderEffectDeactivateP(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectDeactivateP"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + scene.Add(control); + + uint32_t count = control.GetRendererCount(); + control.SetRenderEffect(BackgroundBlurEffect::New()); + + RenderTaskList taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + DALI_TEST_CHECK(count + 1 == control.GetRendererCount()); + + control.ClearRenderEffect(); + taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(1u == taskList.GetTaskCount()); + DALI_TEST_CHECK(count == control.GetRendererCount()); + + END_TEST; +} + +int UtcDaliRenderEffectDeactivateN(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectDeactivateN"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + scene.Add(control); + + try + { + control.ClearRenderEffect(); + DALI_TEST_CHECK(false); + } + catch(Dali::DaliException& e) + { + DALI_TEST_PRINT_ASSERT(e); + DALI_TEST_CHECK(true); + } + + END_TEST; +} + +int UtcDaliRenderEffectRepeatActivateDeactivate(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectRepeatActivateDeactivate"); + + Integration::Scene scene = application.GetScene(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f)); + scene.Add(control); + + BackgroundBlurEffect blurEffect = BackgroundBlurEffect::New(); + for(int i = 0; i < 3; i++) + { + control.SetRenderEffect(blurEffect); // Activate + RenderTaskList taskList = scene.GetRenderTaskList(); + DALI_TEST_CHECK(4u == taskList.GetTaskCount()); + //control.ClearRenderEffect(); // Deactivate, Done automatically on duplicated jobs. + } + + END_TEST; +} diff --git a/dali-scene3d/public-api/controls/scene-view/scene-view.h b/dali-scene3d/public-api/controls/scene-view/scene-view.h index 79e9751..7dc26c0 100644 --- a/dali-scene3d/public-api/controls/scene-view/scene-view.h +++ b/dali-scene3d/public-api/controls/scene-view/scene-view.h @@ -88,6 +88,7 @@ class SceneView; * And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window. * * @note We support to render model well only if glsl version is higher than 300. + * @note We do not support Toolkit::RenderEffect when UseFrameBuffer(false). * * @SINCE_2_1.38 * @code @@ -377,6 +378,7 @@ public: * @brief Sets whether to use FBO or not for the SceneView. * If useFramebuffer is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane. * If useFramebuffer is false, each item in SceneView is rendered on window directly. + * Note that Toolkit::RenderEffect is not supported in this case. * Default is false. * * @SINCE_2_1.38 diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index edee27e..f80d0ac 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_H /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * 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. @@ -61,6 +61,9 @@ #include +#include +#include + #include #include diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index 0641764..fff6769 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -20,9 +20,9 @@ // EXTERNAL INCLUDES #include +#include #include #include -#include #include // INTERNAL INCLUDES @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -600,6 +601,7 @@ public: RegisteredVisualContainer mVisuals; ///< Stores visuals needed by the control, non trivial type so std::vector used. std::string mStyleName; Vector4 mBackgroundColor; ///< The color of the background visual + RenderEffect mRenderEffect; ///< The render effect on this control Vector3* mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this Extents mMargin; ///< The margin values Extents mPadding; ///< The padding values diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp new file mode 100644 index 0000000..4408e0a --- /dev/null +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp @@ -0,0 +1,337 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +//INTERNAL INCLUDES +#include +#include +#include + +namespace +{ +// Default values +static constexpr float BLUR_EFFECT_DOWNSCALE_FACTOR = 0.4f; +static constexpr uint32_t BLUR_EFFECT_PIXEL_RADIUS = 5u; +static constexpr float BLUR_EFFECT_BELL_CURVE_WIDTH = 1.5f; +static constexpr int32_t BLUR_EFFECT_ORDER_INDEX = 101; +static constexpr float BLUR_EFFECT_DIVIDE_ZERO_EPSILON = 0.001f; +} // namespace + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ +// mMultiplierForFraction and mDenominator are for CalculateGaussianWeight(). +// The original equation, +// (1.0f / sqrt(2.0f * Math::PI * mBellCurveWidth)) * exp(-(localOffset * localOffset) * (1.0f / (2.0f * mBellCurveWidth * mBellCurveWidth))); +// is simplified as below: +// mDenominator * exp(-(localOffset * localOffset) * mMultiplierForFraction); + +BlurEffectImpl::BlurEffectImpl(bool isBackground) +: RenderEffectImpl(), + mInternalRoot(Actor::New()), + mDownscaleFactor(BLUR_EFFECT_DOWNSCALE_FACTOR), + mPixelRadius(BLUR_EFFECT_PIXEL_RADIUS), + mBellCurveWidth(BLUR_EFFECT_BELL_CURVE_WIDTH), + mMultiplierForFraction(1.0f / (2.0f * mBellCurveWidth * mBellCurveWidth)), + mDenominator(1.0f / sqrt(2.0f * Math::PI * mBellCurveWidth)), + mIsActivated(false), + mIsBackground(isBackground) +{ +} + +BlurEffectImpl::BlurEffectImpl(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth, bool isBackground) +: RenderEffectImpl(), + mInternalRoot(Actor::New()), + mDownscaleFactor(downscaleFactor), + mPixelRadius((blurRadius >> 2) + 1), + mBellCurveWidth(std::max(bellCurveWidth, BLUR_EFFECT_DIVIDE_ZERO_EPSILON)), + mMultiplierForFraction(1.0f / (2.0f * mBellCurveWidth * mBellCurveWidth)), + mDenominator(1.0f / sqrt(2.0f * Math::PI * mBellCurveWidth)), + mIsActivated(false), + mIsBackground(isBackground) +{ + DALI_ASSERT_ALWAYS(downscaleFactor <= 1.0 && 0.0 < downscaleFactor); +} + +BlurEffectImpl::~BlurEffectImpl() +{ +} + +BlurEffectImplPtr BlurEffectImpl::New(bool isBackground) +{ + BlurEffectImplPtr handle = new BlurEffectImpl(isBackground); + handle->Initialize(); + return handle; +} + +BlurEffectImplPtr BlurEffectImpl::New(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth, bool isBackground) +{ + BlurEffectImplPtr handle = new BlurEffectImpl(downscaleFactor, blurRadius, bellCurveWidth, isBackground); + handle->Initialize(); + return handle; +} + +void BlurEffectImpl::Initialize() +{ + RegisterObject(); // of parent's parent class + + mRenderFullSizeCamera = CameraActor::New(); + mRenderFullSizeCamera.SetInvertYAxis(true); + mRenderFullSizeCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mRenderFullSizeCamera.SetNearClippingPlane(1.0f); + mRenderFullSizeCamera.SetType(Dali::Camera::FREE_LOOK); + mRenderFullSizeCamera.SetFieldOfView(Math::PI / 4.0f); + mInternalRoot.Add(mRenderFullSizeCamera); + + mRenderDownsampledCamera = CameraActor::New(); + mRenderDownsampledCamera.SetInvertYAxis(true); + mRenderDownsampledCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mRenderDownsampledCamera.SetNearClippingPlane(1.0f); + mRenderDownsampledCamera.SetType(Dali::Camera::FREE_LOOK); + mRenderDownsampledCamera.SetFieldOfView(Math::PI / 4.0f); + mInternalRoot.Add(mRenderDownsampledCamera); + + ////////////////////////////////////////////////////// + // Create shaders + + std::ostringstream fragmentStringStream; + fragmentStringStream << "#define NUM_SAMPLES " << mPixelRadius << "\n"; + fragmentStringStream << SHADER_GAUSSIAN_BLUR_VIEW_FRAG; + std::string fragmentSource(fragmentStringStream.str()); + + ////////////////////////////////////////////////////// + // Create actors + mInternalRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + + // Create an actor for performing a horizontal blur on the texture + mHorizontalBlurActor = Actor::New(); + mHorizontalBlurActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + Renderer horizontalBlurRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, fragmentSource.c_str()); + mHorizontalBlurActor.AddRenderer(horizontalBlurRenderer); + mInternalRoot.Add(mHorizontalBlurActor); + + // Create an actor for performing a vertical blur on the texture + mVerticalBlurActor = Actor::New(); + mVerticalBlurActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + Renderer verticalBlurRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, fragmentSource.c_str()); + mVerticalBlurActor.AddRenderer(verticalBlurRenderer); + mInternalRoot.Add(mVerticalBlurActor); +} + +void BlurEffectImpl::Activate() +{ + DALI_ASSERT_ALWAYS(!mIsActivated && + "This effect is already taken. Call Toolkit::Control::ClearRenderEffect(); to free the effect."); + + Toolkit::Control handle = GetOwnerControl(); + DALI_ASSERT_ALWAYS(handle); // RenderEffect::SetOwnerControl(mOwnerControl); was done. + + // Get input texture size + Vector2 size = GetTargetSize(); + if(size == Vector2::ZERO) + { + size = handle.GetNaturalSize(); + if(size == Vector2::ZERO) + { + return; + } + } + DALI_ASSERT_ALWAYS(!(size.x < 0.0f || size.y < 0.0f || uint32_t(size.x) > Dali::GetMaxTextureSize() || uint32_t(size.y) > Dali::GetMaxTextureSize()) && "You need to pass a valid texture size."); + + uint32_t downsampledWidth = static_cast(size.width * mDownscaleFactor); + uint32_t downsampledHeight = static_cast(size.height * mDownscaleFactor); + + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); + + // Prepare resource + // original texture output + mInputBackgroundFrameBuffer = FrameBuffer::New(downsampledWidth, downsampledHeight, FrameBuffer::Attachment::NONE); + Texture inputBackgroundTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, downsampledWidth, downsampledHeight); + mInputBackgroundFrameBuffer.AttachColorTexture(inputBackgroundTexture); + + // half-blurred output + mTemporaryFrameBuffer = FrameBuffer::New(downsampledWidth, downsampledHeight, FrameBuffer::Attachment::NONE); + Texture temporaryTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, downsampledWidth, downsampledHeight); + mTemporaryFrameBuffer.AttachColorTexture(temporaryTexture); + + // blurred output + mSourceFrameBuffer = FrameBuffer::New(downsampledWidth, downsampledHeight, FrameBuffer::Attachment::NONE); + Texture sourceTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, downsampledWidth, downsampledHeight); + mSourceFrameBuffer.AttachColorTexture(sourceTexture); + + // Add BlurActors + mHorizontalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight)); // mTemporaryFrameBuffer + mVerticalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight)); // mSourceFrameBuffer + + // Add CameraActors + float cameraPosConstraintScale = 0.5f / tanf(Math::PI / 4.0f * 0.5f); + + mRenderFullSizeCamera.SetAspectRatio(size.width / size.height); + mRenderFullSizeCamera.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, cameraPosConstraintScale * size.height)); + + mRenderDownsampledCamera.SetAspectRatio(float(downsampledWidth) / float(downsampledHeight)); + mRenderDownsampledCamera.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, cameraPosConstraintScale * size.height * mDownscaleFactor)); + + SetShaderConstants(downsampledWidth, downsampledHeight); + + // Prepare input texture + mSourceRenderTask = taskList.CreateTask(); + if(mIsBackground) + { + mSourceRenderTask.SetSourceActor(Stage::GetCurrent().GetRootLayer()); + mSourceRenderTask.RenderUntil(handle); + } + else + { + mSourceRenderTask.SetSourceActor(handle); + } + mSourceRenderTask.SetOrderIndex(BLUR_EFFECT_ORDER_INDEX); + mSourceRenderTask.SetCameraActor(mRenderFullSizeCamera); + mSourceRenderTask.SetFrameBuffer(mInputBackgroundFrameBuffer); + mSourceRenderTask.SetInputEnabled(false); + mSourceRenderTask.SetExclusive(false); + + // Blur tasks + SetRendererTexture(mHorizontalBlurActor.GetRendererAt(0), mInputBackgroundFrameBuffer); + mHorizontalBlurTask = taskList.CreateTask(); + mHorizontalBlurTask.SetSourceActor(mHorizontalBlurActor); + mHorizontalBlurTask.SetOrderIndex(BLUR_EFFECT_ORDER_INDEX + 1); + mHorizontalBlurTask.SetExclusive(true); + mHorizontalBlurTask.SetInputEnabled(false); + mHorizontalBlurTask.SetCameraActor(mRenderDownsampledCamera); + mHorizontalBlurTask.SetFrameBuffer(mTemporaryFrameBuffer); + + SetRendererTexture(mVerticalBlurActor.GetRendererAt(0), mTemporaryFrameBuffer); + mVerticalBlurTask = taskList.CreateTask(); + mVerticalBlurTask.SetSourceActor(mVerticalBlurActor); + mVerticalBlurTask.SetOrderIndex(BLUR_EFFECT_ORDER_INDEX + 2); + mVerticalBlurTask.SetExclusive(true); + mVerticalBlurTask.SetInputEnabled(false); + mVerticalBlurTask.SetCameraActor(mRenderDownsampledCamera); + mVerticalBlurTask.SetFrameBuffer(mSourceFrameBuffer); + + // Inject output to control + Renderer renderer = GetTargetRenderer(); + if(mIsBackground) + { + renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, Dali::Toolkit::DepthIndex::BACKGROUND - 3); + } + else + { + renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, Dali::Toolkit::DepthIndex::CONTENT); + } + handle.AddRenderer(renderer); + SetRendererTexture(renderer, mSourceFrameBuffer); + + handle.Add(mInternalRoot); + mIsActivated = true; +} + +void BlurEffectImpl::Deactivate() +{ + mIsActivated = false; + + mInternalRoot.Unparent(); + + mInputBackgroundFrameBuffer.Reset(); + mTemporaryFrameBuffer.Reset(); + mSourceFrameBuffer.Reset(); + + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); + taskList.RemoveTask(mHorizontalBlurTask); + taskList.RemoveTask(mVerticalBlurTask); + taskList.RemoveTask(mSourceRenderTask); + + auto ownerControl = GetOwnerControl(); + if(ownerControl) + { + Renderer renderer = GetTargetRenderer(); + ownerControl.RemoveRenderer(renderer); + } +} + +void BlurEffectImpl::SetShaderConstants(float downsampledWidth, float downsampledHeight) +{ + std::vector uvOffsets(mPixelRadius); + std::vector weights(mPixelRadius); + + // generate bell curve kernel + unsigned int halfSize = mPixelRadius * 2; + std::vector halfSideKernel(halfSize); + + halfSideKernel[0] = CalculateGaussianWeight(0.0f); + float totalWeights = halfSideKernel[0]; + for(unsigned int i = 1; i < halfSize; i++) + { + float w = CalculateGaussianWeight(i); + halfSideKernel[i] = w; + totalWeights += w * 2.0f; + } + for(unsigned int i = 0; i < halfSize; i++) + { + halfSideKernel[i] /= totalWeights; + } + halfSideKernel[0] *= 0.5f; + + // compress kernel + for(unsigned int i = 0; i < mPixelRadius; i++) + { + weights[i] = halfSideKernel[2 * i] + halfSideKernel[2 * i + 1]; + uvOffsets[i] = 2.0f * i + halfSideKernel[2 * i + 1] / weights[i]; + } + + // set shader constants + for(unsigned int i = 0; i < mPixelRadius; ++i) + { + mHorizontalBlurActor.RegisterProperty(GetSampleOffsetsPropertyName(i), Vector2(uvOffsets[i] / downsampledWidth, 0.0f)); + mHorizontalBlurActor.RegisterProperty(GetSampleWeightsPropertyName(i), weights[i]); + + mVerticalBlurActor.RegisterProperty(GetSampleOffsetsPropertyName(i), Vector2(0.0f, uvOffsets[i] / downsampledHeight)); + mVerticalBlurActor.RegisterProperty(GetSampleWeightsPropertyName(i), weights[i]); + } +} + +std::string BlurEffectImpl::GetSampleOffsetsPropertyName(unsigned int index) const +{ + std::ostringstream oss; + oss << "uSampleOffsets[" << index << "]"; + return oss.str(); +} + +std::string BlurEffectImpl::GetSampleWeightsPropertyName(unsigned int index) const +{ + std::ostringstream oss; + oss << "uSampleWeights[" << index << "]"; + return oss.str(); +} + +} // namespace Internal +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h new file mode 100644 index 0000000..eb3fdc2 --- /dev/null +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h @@ -0,0 +1,185 @@ +#ifndef DALI_TOOLKIT_INTERNAL_BLUR_EFFECT_H +#define DALI_TOOLKIT_INTERNAL_BLUR_EFFECT_H + +/* + * 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. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +class BlurEffectImpl; + +namespace Internal +{ +using BlurEffectImplPtr = IntrusivePtr; + +class BlurEffectImpl : public RenderEffectImpl +{ +public: + /** + * @brief Creates an initialized BlurEffect implementation, using default settings. The default settings are: + * + * downscaleFactor = 0.4f + * pixelRadius = 5u + * bellCurveWidth = 1.5f + * + * This blur algorithm is used for both foreground and background blurs. + * + * @param[in] isBackground True when blurring background, False otherwise + * @return A handle to a newly allocated Dali resource + */ + + static BlurEffectImplPtr New(bool isBackground); + + /** + * @brief Creates an initialized BlurEffect implementation. + * This blur algorithm is used for both foreground and background blurs. + * + * @param[in] downscaleFactor This value should reside in the range [0.0, 1.0]. + * @param[in] blurRadius The radius of Gaussian kernel. + * @param[in] bellCurveWidth Blur intensity. + * @param[in] isBackground True when blurring background, False otherwise + * @return A handle to a newly allocated Dali resource + */ + static BlurEffectImplPtr New(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth, bool isBackground); + + /** + * @brief Activates blur effect + */ + void Activate() override; + + /** + * @brief Dectivates blur effect + */ + void Deactivate() override; + +protected: + /** + * @brief Creates an uninitialized blur effect implementation + * @param[in] isBackground True when blurring background, False otherwise + */ + BlurEffectImpl(bool isBackground); + + /** + * @brief Creates an uninitialized blur effect implementation + * @param[in] downscaleFactor This value should reside in the range [0.0, 1.0]. + * @param[in] blurRadius The radius of Gaussian kernel. + * @param[in] bellCurveWidth Blur intensity. + * @param[in] isBackground True when blurring background, False otherwise + */ + BlurEffectImpl(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth, bool isBackground); + + /** + * @brief Destructor + */ + virtual ~BlurEffectImpl(); + + /** + * @brief Initializes effect + */ + void Initialize() override; + +private: + // Inner functions + + /** + * @brief Calculates gaussian weight + * @param[in] localOffset Input to the function + */ + inline float CalculateGaussianWeight(float localOffset) const + { + return mDenominator * exp(-(localOffset * localOffset) * mMultiplierForFraction); + } + + /** + * @brief Sets shader constants, gaussian kernel weights and pixel offsets. + * @param[in] downsampledWidth Downsized width of input texture. + * @param[in] downsampledHeight Downsized height of input texture. + */ + void SetShaderConstants(float downsampledWidth, float downsampledHeight); + + /** + * @brief Get an offset property in std::string format + * @param[in] index Property's index + * @return A string for shader + */ + std::string GetSampleOffsetsPropertyName(unsigned int index) const; + + /** + * @brief Get a weight property in std::string format + * @param[in] index Property's index + * @return A string for shader + */ + std::string GetSampleWeightsPropertyName(unsigned int index) const; + + BlurEffectImpl(const BlurEffectImpl&) = delete; + BlurEffectImpl(BlurEffectImpl&&) = delete; + BlurEffectImpl& operator=(BlurEffectImpl&&) = delete; // no move() + BlurEffectImpl& operator=(const BlurEffectImpl&) = delete; // no copy() + +private: + // Camera actors + CameraActor mRenderFullSizeCamera; + CameraActor mRenderDownsampledCamera; + + // Resource + FrameBuffer mInputBackgroundFrameBuffer; // Input. Background. What to blur. + + Actor mInternalRoot; + Actor mHorizontalBlurActor; + RenderTask mHorizontalBlurTask; + FrameBuffer mTemporaryFrameBuffer; + Actor mVerticalBlurActor; + RenderTask mVerticalBlurTask; + + FrameBuffer mSourceFrameBuffer; // Output. Blurred background texture for mOwnerControl and mRenderer. + RenderTask mSourceRenderTask; + + // Variables + Pixel::Format mPixelFormat; + float mDownscaleFactor; + uint32_t mPixelRadius; + float mBellCurveWidth; + float mMultiplierForFraction; + float mDenominator; + + bool mIsActivated : 1; + bool mIsBackground : 1; +}; +} // namespace Internal + +inline Toolkit::Internal::BlurEffectImpl& GetImplementation(Toolkit::BackgroundBlurEffect& obj) +{ + BaseObject& handle = obj.GetBaseObject(); + return static_cast(handle); +} + +inline const Toolkit::Internal::BlurEffectImpl& GetImplementation(const Toolkit::BackgroundBlurEffect& obj) +{ + const BaseObject& handle = obj.GetBaseObject(); + return static_cast(handle); +} + +} // namespace Toolkit +} // namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_BACKGROUND_BLUR_EFFECT_H diff --git a/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp new file mode 100644 index 0000000..ae3a36d --- /dev/null +++ b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp @@ -0,0 +1,85 @@ +/* + * 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 + +// INTERNAL INCLUDES +#include +#include + +#include +#include + +namespace +{ +static constexpr float SIZE_STEP_CONDITION = 3.0f; +} // namespace + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ +RenderEffectImpl::~RenderEffectImpl() = default; + +void RenderEffectImpl::SetOwnerControl(Dali::Toolkit::Control control) +{ + if(mOwnerControl) + { + Deactivate(); + mOwnerControl.RemovePropertyNotification(mSizeNotification); + } + + mOwnerControl = control; + + if(mOwnerControl) + { + mTargetSize = mOwnerControl.GetProperty(Actor::Property::SIZE); + mRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE); + + mSizeNotification = control.AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION)); + mSizeNotification.NotifySignal().Connect(this, &RenderEffectImpl::OnSizeSet); + } +} + +void RenderEffectImpl::OnSizeSet(PropertyNotification& source) +{ + mTargetSize = mOwnerControl.GetProperty(Actor::Property::SIZE); + Deactivate(); + Activate(); +} + +Renderer RenderEffectImpl::GetTargetRenderer() const +{ + return mRenderer; +} + +Toolkit::Control RenderEffectImpl::GetOwnerControl() const +{ + return mOwnerControl; +} + +Vector2 RenderEffectImpl::GetTargetSize() const +{ + return mTargetSize; +} + +} // namespace Internal +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/internal/controls/render-effects/render-effect-impl.h b/dali-toolkit/internal/controls/render-effects/render-effect-impl.h new file mode 100644 index 0000000..8a21c84 --- /dev/null +++ b/dali-toolkit/internal/controls/render-effects/render-effect-impl.h @@ -0,0 +1,121 @@ +#ifndef DALI_TOOLKIT_INTERNAL_BACKGROUND_EFFECT_H +#define DALI_TOOLKIT_INTERNAL_BACKGROUND_EFFECT_H + +/* + * 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. + * + */ + +//INTERNAL INCLUDES +#include + +// EXTERNAL INCLUDE +#include + +namespace Dali +{ +namespace Toolkit +{ +class RenderEffectImpl; + +namespace Internal +{ +using RenderEffectImplPtr = IntrusivePtr; + +class RenderEffectImpl : public BaseObject, public ConnectionTracker +{ +public: + /** + * @brief Sets owner Control. Applies effect on the owner. + * @param[in] control The owner control to apply RenderEffect. + */ + void SetOwnerControl(Dali::Toolkit::Control control); + + /** + * @brief Get Owner control. + * @return mOwnerControl + */ + Toolkit::Control GetOwnerControl() const; + + /** + * @brief Activate effect. + */ + virtual void Activate() = 0; + + /** + * @brief Deactivate effect. + */ + virtual void Deactivate() = 0; + +protected: + /** + * @copydoc Dali::Toolkit::RenderEffect::RenderEffect + */ + RenderEffectImpl() = default; + + /** + * @copydoc Dali::Toolkit::RenderEffect::~RenderEffect + */ + virtual ~RenderEffectImpl() override; + + RenderEffectImpl(const RenderEffectImpl&) = delete; + RenderEffectImpl(RenderEffectImpl&&) = delete; + RenderEffectImpl& operator=(RenderEffectImpl&&) = delete; // no move() + RenderEffectImpl& operator=(const RenderEffectImpl&) = delete; // no copy() + + virtual void Initialize() = 0; + + /** + * @brief Get target renderer + * On internal Activate(), the renderer draws our visual effect and is added to our Owner control. + * @return mRenderer + */ + Renderer GetTargetRenderer() const; + + /** + * @brief Callback when the size changes. + */ + void OnSizeSet(PropertyNotification& source); + + /** + * @brief The final size of the owner after resizing or relayouts. + * @return mTargetSize + */ + Vector2 GetTargetSize() const; + +private: + Dali::Renderer mRenderer; // An additional renderer for mOwnerControl + Dali::Toolkit::Control mOwnerControl; + + Vector2 mTargetSize; // The final size of mOwnerControl + PropertyNotification mSizeNotification; // Resize/Relayout signal +}; +} // namespace Internal + +inline Toolkit::Internal::RenderEffectImpl& GetImplementation(Toolkit::RenderEffect& obj) +{ + BaseObject& handle = obj.GetBaseObject(); + return static_cast(handle); +} + +inline const Toolkit::Internal::RenderEffectImpl& GetImplementation(const Toolkit::RenderEffect& obj) +{ + const BaseObject& handle = obj.GetBaseObject(); + return static_cast(handle); +} + +} // namespace Toolkit +} // namespace Dali +#endif // DALI_TOOLKIT_INTERNAL_BACKGROUND_EFFECT_H diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index e9ae5b7..771fe8d 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -64,6 +64,8 @@ SET( toolkit_src_files ${toolkit_src_dir}/visuals/visual-url.cpp ${toolkit_src_dir}/visuals/wireframe/wireframe-visual.cpp ${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/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 diff --git a/dali-toolkit/internal/graphics/shaders/control-renderers.frag b/dali-toolkit/internal/graphics/shaders/control-renderers.frag index e29e6a1..e0d08bf 100644 --- a/dali-toolkit/internal/graphics/shaders/control-renderers.frag +++ b/dali-toolkit/internal/graphics/shaders/control-renderers.frag @@ -1,5 +1,5 @@ -precision mediump float; -varying mediump vec2 vTexCoord; +precision highp float; +varying highp vec2 vTexCoord; uniform sampler2D sTexture; uniform vec4 uColor; diff --git a/dali-toolkit/internal/graphics/shaders/control-renderers.vert b/dali-toolkit/internal/graphics/shaders/control-renderers.vert index e7e930f..0183ee4 100644 --- a/dali-toolkit/internal/graphics/shaders/control-renderers.vert +++ b/dali-toolkit/internal/graphics/shaders/control-renderers.vert @@ -1,12 +1,12 @@ -precision mediump float; -attribute mediump vec2 aPosition; -varying mediump vec2 vTexCoord; -uniform mediump mat4 uMvpMatrix; -uniform mediump vec3 uSize; +precision highp float; +attribute highp vec2 aPosition; +varying highp vec2 vTexCoord; +uniform highp mat4 uMvpMatrix; +uniform highp vec3 uSize; void main() { - mediump vec4 vertexPosition = vec4(aPosition * uSize.xy, 0.0, 1.0); + highp vec4 vertexPosition = vec4(aPosition * uSize.xy, 0.0, 1.0); vTexCoord = aPosition + vec2(0.5); gl_Position = uMvpMatrix * vertexPosition; } diff --git a/dali-toolkit/internal/graphics/shaders/gaussian-blur-view.frag b/dali-toolkit/internal/graphics/shaders/gaussian-blur-view.frag index 6613b0f..626d27b 100644 --- a/dali-toolkit/internal/graphics/shaders/gaussian-blur-view.frag +++ b/dali-toolkit/internal/graphics/shaders/gaussian-blur-view.frag @@ -1,15 +1,15 @@ -varying mediump vec2 vTexCoord; +varying highp vec2 vTexCoord; uniform sampler2D sTexture; uniform lowp vec4 uColor; -uniform mediump vec2 uSampleOffsets[NUM_SAMPLES]; -uniform mediump float uSampleWeights[NUM_SAMPLES]; +uniform highp vec2 uSampleOffsets[NUM_SAMPLES]; +uniform highp float uSampleWeights[NUM_SAMPLES]; void main() { - mediump vec4 col = texture2D(sTexture, vTexCoord + uSampleOffsets[0]) * uSampleWeights[0]; - for (int i=1; i #include #include -#include #include +#include #include #include +#include #include #include #include @@ -166,6 +167,36 @@ void Control::ClearBackground() RelayoutRequest(); } +void Control::SetRenderEffect(Toolkit::RenderEffect effect) +{ + if(mImpl->mRenderEffect == effect) + { + return; + } + mImpl->mRenderEffect = effect; + + BaseObject& handle = effect.GetBaseObject(); + Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(&handle); + + Dali::Toolkit::Control ownerControl(GetOwner()); + object->SetOwnerControl(ownerControl); + object->Activate(); +} + +void Control::ClearRenderEffect() +{ + BaseObject& handle = mImpl->mRenderEffect.GetBaseObject(); + Toolkit::Internal::RenderEffectImpl* object = dynamic_cast(&handle); + + if(!object) + { + DALI_ASSERT_ALWAYS(false && "Set any render effect before you clear."); + } + + object->Deactivate(); + object->SetOwnerControl(Toolkit::Control()); +} + void Control::SetResourceReady() { Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(*this); @@ -602,7 +633,7 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper void Control::OnSizeSet(const Vector3& targetSize) { - Vector2 size(targetSize); + Vector2 size(targetSize); Toolkit::Visual::Base visual = mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND); if(visual) { diff --git a/dali-toolkit/public-api/controls/control-impl.h b/dali-toolkit/public-api/controls/control-impl.h index 9e2915e..4fe0781 100644 --- a/dali-toolkit/public-api/controls/control-impl.h +++ b/dali-toolkit/public-api/controls/control-impl.h @@ -115,6 +115,16 @@ public: void ClearBackground(); /** + * @copydoc Dali::Toolkit::Control::SetRenderEffect + */ + void SetRenderEffect(Toolkit::RenderEffect effect); + + /** + * @copydoc Dali::Toolkit::Control::ClearRenderEffect + */ + void ClearRenderEffect(); + + /** * @brief Called when resources of control are ready. this api does not request relayout. */ void SetResourceReady(); diff --git a/dali-toolkit/public-api/controls/control.cpp b/dali-toolkit/public-api/controls/control.cpp index 2e918f0..c163378 100644 --- a/dali-toolkit/public-api/controls/control.cpp +++ b/dali-toolkit/public-api/controls/control.cpp @@ -115,6 +115,16 @@ void Control::ClearBackground() Internal::GetImplementation(*this).ClearBackground(); } +void Control::SetRenderEffect(Toolkit::RenderEffect effect) +{ + Internal::GetImplementation(*this).SetRenderEffect(effect); +} + +void Control::ClearRenderEffect() +{ + Internal::GetImplementation(*this).ClearRenderEffect(); +} + bool Control::IsResourceReady() const { return Internal::GetImplementation(*this).IsResourceReady(); diff --git a/dali-toolkit/public-api/controls/control.h b/dali-toolkit/public-api/controls/control.h index e4e90a2..7da13e8 100644 --- a/dali-toolkit/public-api/controls/control.h +++ b/dali-toolkit/public-api/controls/control.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CONTROL_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * 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. @@ -33,6 +33,7 @@ namespace Dali { namespace Toolkit { +class RenderEffect; //Forward declarations. namespace Internal @@ -147,16 +148,16 @@ public: */ enum Direction { - LEFT, ///< Move keyboard focus towards the left direction @SINCE_1_0.0 - RIGHT, ///< Move keyboard focus towards the right direction @SINCE_1_0.0 - UP, ///< Move keyboard focus towards the up direction @SINCE_1_0.0 - DOWN, ///< Move keyboard focus towards the down direction @SINCE_1_0.0 - PAGE_UP, ///< Move keyboard focus towards the previous page direction @SINCE_1_2.14 - PAGE_DOWN, ///< Move keyboard focus towards the next page direction @SINCE_1_2.14 - FORWARD, ///< Move keyboard focus towards the forward direction @SINCE_2_1.10 - BACKWARD, ///< Move keyboard focus towards the backward direction @SINCE_2_1.10 - CLOCKWISE, ///< Move keyboard focus towards the clockwise direction @SINCE_2_1.14 - COUNTER_CLOCKWISE, ///< Move keyboard focus towards the counter clockwise direction @SINCE_2_1.14 + LEFT, ///< Move keyboard focus towards the left direction @SINCE_1_0.0 + RIGHT, ///< Move keyboard focus towards the right direction @SINCE_1_0.0 + UP, ///< Move keyboard focus towards the up direction @SINCE_1_0.0 + DOWN, ///< Move keyboard focus towards the down direction @SINCE_1_0.0 + PAGE_UP, ///< Move keyboard focus towards the previous page direction @SINCE_1_2.14 + PAGE_DOWN, ///< Move keyboard focus towards the next page direction @SINCE_1_2.14 + FORWARD, ///< Move keyboard focus towards the forward direction @SINCE_2_1.10 + BACKWARD, ///< Move keyboard focus towards the backward direction @SINCE_2_1.10 + CLOCKWISE, ///< Move keyboard focus towards the clockwise direction @SINCE_2_1.14 + COUNTER_CLOCKWISE, ///< Move keyboard focus towards the counter clockwise direction @SINCE_2_1.14 }; }; @@ -172,7 +173,6 @@ public: typedef Signal ResourceReadySignalType; public: // Creation & Destruction - /** * @brief Additional control behaviour flags for the control constructor. * @note TODO : Currunt code is hard-coded. We Should sync type values as @@ -382,6 +382,22 @@ public: */ void ClearBackground(); + /** + * @brief Sets RenderEffect to this control. + * + * @SINCE_2_3.25 + * @param[in] effect RenderEffect to add. + * + * @note Every effect inherits RenderEffect. + */ + void SetRenderEffect(Toolkit::RenderEffect effect); + + /** + * @brief Clears RenderEffect of this control, if exists. + * @SINCE_2_3.25 + */ + void ClearRenderEffect(); + // Resources /** diff --git a/dali-toolkit/public-api/controls/render-effects/background-blur-effect.cpp b/dali-toolkit/public-api/controls/render-effects/background-blur-effect.cpp new file mode 100644 index 0000000..32ba804 --- /dev/null +++ b/dali-toolkit/public-api/controls/render-effects/background-blur-effect.cpp @@ -0,0 +1,55 @@ +/* + * 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 + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +BackgroundBlurEffect::BackgroundBlurEffect() = default; + +BackgroundBlurEffect::BackgroundBlurEffect(const BackgroundBlurEffect& handle) +: RenderEffect(handle) +{ +} + +BackgroundBlurEffect::BackgroundBlurEffect(Internal::BlurEffectImpl* blurEffectImpl) +: RenderEffect(blurEffectImpl) +{ +} + +BackgroundBlurEffect::~BackgroundBlurEffect() = default; + +BackgroundBlurEffect BackgroundBlurEffect::New() +{ + Internal::BlurEffectImplPtr internal = Internal::BlurEffectImpl::New(true); + return BackgroundBlurEffect(internal.Get()); +} + +BackgroundBlurEffect BackgroundBlurEffect::New(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth) +{ + Internal::BlurEffectImplPtr internal = Internal::BlurEffectImpl::New(downscaleFactor, blurRadius, bellCurveWidth, true); + return BackgroundBlurEffect(internal.Get()); +} + +}// namespace Toolkit +}// namespace Dali diff --git a/dali-toolkit/public-api/controls/render-effects/background-blur-effect.h b/dali-toolkit/public-api/controls/render-effects/background-blur-effect.h new file mode 100644 index 0000000..7d0bf98 --- /dev/null +++ b/dali-toolkit/public-api/controls/render-effects/background-blur-effect.h @@ -0,0 +1,106 @@ +#ifndef DALI_TOOLKIT_BACKGROUND_BLUR_EFFECT_H +#define DALI_TOOLKIT_BACKGROUND_BLUR_EFFECT_H + +/* + * 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. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal DALI_INTERNAL +{ +class BlurEffectImpl; +} // namespace DALI_INTERNAL + +/** + * @brief BackgroundBlurEffect is a visual effect that blurs owner control's background. + * This class is a concrete class from RenderEffect interface. + * Add this effect to a control, clear manually to deactivate. + * + * Toolkit::Control control = Toolkit::Control::New(); + * parent.Add(control); + * control.SetRenderEffect(BackgroundBlurEffect::New()); // Activate + * ... + * control.ClearRenderEffect(); // Deactivate + * + * Note that tree hierarchy matters for BackgroundBlurEffect. You should determine "what is the background". + * Add() should preceed SetRenderEffect(), and the effect cannot have multiple owner controls. + * + * @SINCE_2_3.28 + */ +class DALI_TOOLKIT_API BackgroundBlurEffect : public RenderEffect +{ +public: + /** + * @brief Creates an initialized BackgroundBlurEffect, using default settings. The default settings are: + * + * downscaleFactor = 0.4f + * pixelRadius = 5u + * bellCurveWidth = 1.5f + * + * @SINCE_2_3.28 + * @return A handle to a newly allocated Dali resource + */ + static BackgroundBlurEffect New(); + + /** + * @brief Creates an initialized BackgroundBlurEffect. + * @param[in] downscaleFactor This value should reside in the range [0.0, 1.0]. + * @param[in] blurRadius The radius of Gaussian kernel. + * @param[in] bellCurveWidth Blur intensity. + * @SINCE_2_3.28 + * @return A handle to a newly allocated Dali resource + */ + static BackgroundBlurEffect New(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth); + + /** + * @brief Creates an uninitialized blur effect. + * @SINCE_2_3.28 + */ + BackgroundBlurEffect(); + + /** + * @brief Copy constructor. + * @SINCE_2_3.28 + */ + BackgroundBlurEffect(const BackgroundBlurEffect& handle); + + /** + * @brief Destructor + * @SINCE_2_3.28 + */ + ~BackgroundBlurEffect(); + +public: // Not intended for use by Application developers + ///@cond internal + /** + * @brief Creates a handle using the Toolkit::Internal implementation. + * @SINCE_2_3.28 + * @param[in] blurEffectImpl The UI Control implementation. + */ + explicit DALI_INTERNAL BackgroundBlurEffect(Internal::BlurEffectImpl* blurEffectImpl); + ///@endcond +}; + +} // namespace Toolkit +} // namespace Dali + +#endif //DALI_TOOLKIT_BACKGROUND_BLUR_EFFECT_H diff --git a/dali-toolkit/public-api/controls/render-effects/render-effect.cpp b/dali-toolkit/public-api/controls/render-effects/render-effect.cpp new file mode 100644 index 0000000..804c8e2 --- /dev/null +++ b/dali-toolkit/public-api/controls/render-effects/render-effect.cpp @@ -0,0 +1,42 @@ +/* + * 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 + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ + +RenderEffect::RenderEffect(const RenderEffect& handle) +: BaseHandle(handle) +{ +} + +RenderEffect::RenderEffect(Internal::RenderEffectImpl* renderEffectImpl) +: BaseHandle(renderEffectImpl) +{ +} + +RenderEffect::~RenderEffect() = default; + +} // namespace Toolkit +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/render-effects/render-effect.h b/dali-toolkit/public-api/controls/render-effects/render-effect.h new file mode 100644 index 0000000..02516b7 --- /dev/null +++ b/dali-toolkit/public-api/controls/render-effects/render-effect.h @@ -0,0 +1,88 @@ +#ifndef DALI_TOOLKIT_RENDER_EFFECT_H +#define DALI_TOOLKIT_RENDER_EFFECT_H + +/* + * 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 +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +class Control; +namespace Internal DALI_INTERNAL +{ +class Control; +class RenderEffectImpl; +} // namespace DALI_INTERNAL + +/** + * @brief + * RenderEffect is an interface for visual effects. + * You do not ::New() an interface. + * + * Each effect has a single owner Control. + * + * Used internal at: + * Toolkit::Control::SetRenderEffect(Toolkit::RenderEffect effect); + * Toolkit::Control::ClearRenderEffect(); + * + * @SINCE_2_3.28 + */ +class DALI_TOOLKIT_API RenderEffect : public BaseHandle +{ +public: + /** + * @brief Creates an uninitialized effect. + * @SINCE_2_3.28 + */ + RenderEffect() = default; + + /** + * @brief Copy constructor. Creates another handle that points to the same real object. + * @SINCE_2_3.28 + */ + RenderEffect(const RenderEffect& handle); + + /** + * @brief Destructor. + * This is non-virtual since derived Handle types must not contain data or virtual methods. + * @SINCE_2_3.28 + */ + ~RenderEffect(); + +public: // Not intended for Application developers + ///@cond internal + /** + * @brief Creates a handle using the Toolkit::Internal implementation. + * @SINCE_2_3.28 + * @param[in] renderEffectImpl The UI Control implementation. + */ + explicit DALI_INTERNAL RenderEffect(Internal::RenderEffectImpl* renderEffectImpl); + ///@endcond +}; + +} // namespace Toolkit +} // namespace Dali + +#endif //DALI_TOOLKIT_RENDER_EFFECT_H diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index 833bfbf..6da2012 100644 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -13,6 +13,8 @@ SET( public_api_src_files ${public_api_src_dir}/controls/image-view/image-view.cpp ${public_api_src_dir}/controls/model3d-view/model3d-view.cpp ${public_api_src_dir}/controls/progress-bar/progress-bar.cpp + ${public_api_src_dir}/controls/render-effects/render-effect.cpp + ${public_api_src_dir}/controls/render-effects/background-blur-effect.cpp ${public_api_src_dir}/controls/scrollable/item-view/default-item-layout.cpp ${public_api_src_dir}/controls/scrollable/item-view/item-layout.cpp ${public_api_src_dir}/controls/scrollable/item-view/item-view.cpp @@ -104,6 +106,11 @@ SET( public_api_progress_bar_header_files ${public_api_src_dir}/controls/progress-bar/progress-bar.h ) +SET( public_api_render_effects_header_files + ${public_api_src_dir}/controls/render-effects/render-effect.h + ${public_api_src_dir}/controls/render-effects/background-blur-effect.h +) + SET( public_api_scrollable_header_files ${public_api_src_dir}/controls/scrollable/scrollable.h ) @@ -198,6 +205,7 @@ SET( PUBLIC_API_HEADERS ${PUBLIC_API_HEADERS} ${public_api_item_view_header_files} ${public_api_image_loader_header_files} ${public_api_progress_bar_header_files} + ${public_api_render_effects_header_files} ${public_api_scrollable_header_files} ${public_api_scroll_view_header_files} ${public_api_slider_header_files}