From 9b1f44ccfd55e82aeabc86f1aa670a2a2b0fc56a Mon Sep 17 00:00:00 2001 From: jmm Date: Wed, 10 Jul 2024 20:57:31 +0900 Subject: [PATCH] Resolve RenderEffect Size and CornerRadius issues Change-Id: Ic0cb535464532632ca009af9be9aefaa69339b97 --- .../src/dali-toolkit/utc-Dali-RenderEffect.cpp | 37 +++++++++++++++- .../controls/render-effects/blur-effect-impl.cpp | 49 +++++++++++++++++----- .../controls/render-effects/blur-effect-impl.h | 7 ++++ .../controls/render-effects/render-effect-impl.cpp | 2 +- .../internal/graphics/shaders/render-effect.frag | 31 ++++---------- .../internal/graphics/shaders/render-effect.vert | 7 ++++ 6 files changed, 98 insertions(+), 35 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp index 8e08387..bc33709 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp @@ -18,6 +18,7 @@ #include #include #include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -217,7 +218,6 @@ int UtcDaliRenderEffectResize(void) Integration::Scene scene = application.GetScene(); Control control = Control::New(); control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - control.SetProperty(Actor::Property::SIZE, Vector2(3.0f, 3.0f)); scene.Add(control); control.SetRenderEffect(BackgroundBlurEffect::New()); @@ -263,7 +263,11 @@ int UtcDaliRenderEffectSynchronizeBackgroundCornerRadius(void) Renderer renderer = control.GetRendererAt(1u); Vector4 radius = Vector4::ZERO; - renderer.GetProperty(renderer.GetPropertyIndex(std::string("uRadius"))).Get(radius); + renderer.GetProperty(renderer.GetPropertyIndex(std::string("uCornerRadius"))).Get(radius); + + Toolkit::Visual::Transform::Policy::Type policy; + renderer.GetProperty(renderer.GetPropertyIndex(std::string("uCornerRadiusPolicy"))).Get(policy); + DALI_TEST_CHECK(policy == 1); DALI_TEST_CHECK(radius.x == 30.0f); DALI_TEST_CHECK(radius.y == 30.0f); @@ -272,3 +276,32 @@ int UtcDaliRenderEffectSynchronizeBackgroundCornerRadius(void) END_TEST; } + +int UtcDaliRenderEffectInvalidTargetSize(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliRenderEffectInvalidTargetSize"); + + Integration::Scene scene = application.GetScene(); + const uint32_t maxTextureSize = Dali::GetMaxTextureSize(); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + control.SetProperty(Actor::Property::SIZE_WIDTH, maxTextureSize + 1000.0f); + control.SetProperty(Actor::Property::SIZE_HEIGHT, maxTextureSize + 1000.0f); + scene.Add(control); + control.SetRenderEffect(BackgroundBlurEffect::New(0.4f, 40)); + + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK(true); // no error + + control.SetProperty(Actor::Property::SIZE_WIDTH, -10.0f); + control.SetProperty(Actor::Property::SIZE_HEIGHT, -10.0f); + + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK(true); // no error + + END_TEST; +} diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp index 9d8b2a4..ac46a2e 100644 --- a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp @@ -142,6 +142,29 @@ void BlurEffectImpl::Initialize() mInternalRoot.Add(mVerticalBlurActor); } +Vector2 BlurEffectImpl::GetTargetSizeForValidTexture() +{ + Vector2 size = GetTargetSize(); + if(size == Vector2::ZERO) + { + size = GetOwnerControl().GetNaturalSize(); + } + + if(size == Vector2::ZERO || size.x < 0.0f || size.y < 0.0f) + { + return Vector2::ZERO; + } + + const uint32_t maxTextureSize = Dali::GetMaxTextureSize(); + if(uint32_t(size.x) > maxTextureSize || uint32_t(size.y) > maxTextureSize) + { + uint32_t denominator = std::max(size.x, size.y); + size.x = (size.x * maxTextureSize / denominator); + size.y = (size.y * maxTextureSize / denominator); + } + return size; +} + void BlurEffectImpl::Activate() { if(mIsActivated) @@ -152,20 +175,22 @@ void BlurEffectImpl::Activate() Toolkit::Control ownerControl = GetOwnerControl(); DALI_ASSERT_ALWAYS(ownerControl && "Set the owner of RenderEffect before you activate."); - // Get input texture size - Vector2 size = GetTargetSize(); + // Get/Set sizes + Vector2 size = GetTargetSizeForValidTexture(); if(size == Vector2::ZERO) { - size = ownerControl.GetNaturalSize(); - if(size == Vector2::ZERO) - { - return; - } + 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); + if(downsampledWidth == 0u) + { + downsampledWidth = 1u; + } + if(downsampledHeight == 0u) + { + downsampledHeight = 1u; + } RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); @@ -336,8 +361,12 @@ void BlurEffectImpl::SynchronizeBackgroundCornerRadius() Vector4 radius = Vector4::ZERO; map[Toolkit::DevelVisual::Property::CORNER_RADIUS].Get(radius); + Visual::Transform::Policy::Type policy; + map[Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY].Get(policy); + Renderer renderer = GetTargetRenderer(); - renderer.RegisterProperty("uRadius", radius); + renderer.RegisterProperty("uCornerRadius", radius); + renderer.RegisterProperty("uCornerRadiusPolicy", static_cast(policy)); } } // namespace Internal diff --git a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h index 3c6a293..5e963ba 100644 --- a/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h +++ b/dali-toolkit/internal/controls/render-effects/blur-effect-impl.h @@ -97,6 +97,13 @@ protected: private: // Inner functions + /** + * @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(); /** * @brief Calculates gaussian weight diff --git a/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp index 9c874d7..332ab76 100644 --- a/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp +++ b/dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp @@ -75,7 +75,7 @@ void RenderEffectImpl::OnSizeSet(PropertyNotification& source) { if(mOwnerControl) { - mTargetSize = mOwnerControl.GetProperty(Actor::Property::SIZE); + mTargetSize = mOwnerControl.GetCurrentProperty(Actor::Property::SIZE); Deactivate(); Activate(); } diff --git a/dali-toolkit/internal/graphics/shaders/render-effect.frag b/dali-toolkit/internal/graphics/shaders/render-effect.frag index bed870a..9ad5306 100644 --- a/dali-toolkit/internal/graphics/shaders/render-effect.frag +++ b/dali-toolkit/internal/graphics/shaders/render-effect.frag @@ -1,9 +1,9 @@ precision highp float; varying highp vec2 vFragCoord; varying highp vec2 vTexCoord; +varying highp vec4 vCornerRadius; uniform highp vec3 uSize; uniform sampler2D sTexture; -uniform highp vec4 uRadius; highp float nrand(const in vec2 uv) { @@ -28,31 +28,18 @@ float roundedBoxSDF(vec2 PixelPositionFromCenter, vec2 RectangleEdgePositionFrom - Radius; } -float getCurrentRadius() -{ - if(vTexCoord.x < 0.5 && vTexCoord.y < 0.5) - { - return uRadius.x; - } - else if(vTexCoord.x < 0.5 && vTexCoord.y > 0.5) - { - return uRadius.y; - } - else if(vTexCoord.x > 0.5 && vTexCoord.y > 0.5) - { - return uRadius.z; - } - else - { - return uRadius.w; - } -} - void main() { gl_FragColor = texture2D(sTexture, vTexCoord); - float radius = getCurrentRadius(); + highp vec2 location = vTexCoord.xy - vec2(0.5); + float radius = + mix( + mix(vCornerRadius.x, vCornerRadius.y, sign(location.x)*0.5 + 0.5), + mix(vCornerRadius.w, vCornerRadius.z, sign(location.x)*0.5 + 0.5), + sign(location.y) * 0.5 + 0.5 + ); + float edgeSoftness = min(1.0, radius); float distance = roundedBoxSDF(vFragCoord.xy - (uSize.xy/2.0), uSize.xy/2.0, radius); diff --git a/dali-toolkit/internal/graphics/shaders/render-effect.vert b/dali-toolkit/internal/graphics/shaders/render-effect.vert index 2de4f92..b8ae74d 100644 --- a/dali-toolkit/internal/graphics/shaders/render-effect.vert +++ b/dali-toolkit/internal/graphics/shaders/render-effect.vert @@ -2,8 +2,11 @@ precision highp float; attribute highp vec2 aPosition; varying highp vec2 vFragCoord; varying highp vec2 vTexCoord; +varying highp vec4 vCornerRadius; //output uniform highp mat4 uMvpMatrix; uniform highp vec3 uSize; +uniform highp vec4 uCornerRadius; //input +uniform highp float uCornerRadiusPolicy; void main() { @@ -11,4 +14,8 @@ void main() vFragCoord = vertexPosition.xy + uSize.xy/2.0; vTexCoord = aPosition + vec2(0.5); gl_Position = uMvpMatrix * vertexPosition; + + highp float minSize = min(uSize.x, uSize.y); + vCornerRadius = mix(uCornerRadius * minSize, uCornerRadius, uCornerRadiusPolicy); + vCornerRadius = min(vCornerRadius, minSize * 0.5); } -- 2.7.4