Resolve RenderEffect Size and CornerRadius issues 56/314356/3
authorjmm <j0064423.lee@samsung.com>
Wed, 10 Jul 2024 11:57:31 +0000 (20:57 +0900)
committerjmm <j0064423.lee@samsung.com>
Wed, 10 Jul 2024 13:07:22 +0000 (22:07 +0900)
Change-Id: Ic0cb535464532632ca009af9be9aefaa69339b97

automated-tests/src/dali-toolkit/utc-Dali-RenderEffect.cpp
dali-toolkit/internal/controls/render-effects/blur-effect-impl.cpp
dali-toolkit/internal/controls/render-effects/blur-effect-impl.h
dali-toolkit/internal/controls/render-effects/render-effect-impl.cpp
dali-toolkit/internal/graphics/shaders/render-effect.frag
dali-toolkit/internal/graphics/shaders/render-effect.vert

index 8e08387fb8ea057757c1da0a31991a86185a394b..bc33709ce6dfa2ac4168577b4f1ca5407f7da0f3 100644 (file)
@@ -18,6 +18,7 @@
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/public-api/controls/render-effects/background-blur-effect.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 
 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;
+}
index 9d8b2a44c79c5b3821cca02166423d66f209b81c..ac46a2e838e74c70b7092bac1bb929a9f6f2aa70 100644 (file)
@@ -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<uint32_t>(size.width * mDownscaleFactor);
   uint32_t downsampledHeight = static_cast<uint32_t>(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<float>(policy));
 }
 
 } // namespace Internal
index 3c6a29363aa44aa8a1ba015cd16fcdcc3e3f3157..5e963ba81d40cbca5f6b0989e976c51a6b2733f3 100644 (file)
@@ -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
index 9c874d7ad09fa53470f69df63219c3c0aa67555f..332ab76a7566ea2f028f99655cb491e23e993d85 100644 (file)
@@ -75,7 +75,7 @@ void RenderEffectImpl::OnSizeSet(PropertyNotification& source)
 {
   if(mOwnerControl)
   {
-    mTargetSize = mOwnerControl.GetProperty<Vector2>(Actor::Property::SIZE);
+    mTargetSize = mOwnerControl.GetCurrentProperty<Vector2>(Actor::Property::SIZE);
     Deactivate();
     Activate();
   }
index bed870a846af1beadc6326cc4539881243c4029a..9ad5306f586f113ed1e006b49f7deab36733c4e8 100644 (file)
@@ -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);
 
index 2de4f92b156c8610b820acd38aea83dbe6065df9..b8ae74d52986d86022bbcd2bd7bf09778b2fb786 100644 (file)
@@ -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);
 }