Add RenderEffectImpl::SynchronizeBackgroundCornerRadius() 80/312480/10
authorjmm <j0064423.lee@samsung.com>
Mon, 10 Jun 2024 12:46:41 +0000 (21:46 +0900)
committerjmm <j0064423.lee@samsung.com>
Wed, 19 Jun 2024 05:31:37 +0000 (14:31 +0900)
Change-Id: I3eedb39693907c128e67e480fb74f28ee622a461

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 [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/render-effect.vert [new file with mode: 0644]
dali-toolkit/public-api/controls/render-effects/render-effect.cpp

index 5f1933b..0f0f1db 100644 (file)
@@ -16,6 +16,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>
 
 using namespace Dali;
@@ -42,7 +43,7 @@ int UtcDaliRenderEffectNewN(void)
 
   try
   {
-    BackgroundBlurEffect blurEffect = BackgroundBlurEffect::New(-0.5f, 10.0f, 10.0f);
+    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);
   }
@@ -189,3 +190,41 @@ int UtcDaliRenderEffectRepeatActivateDeactivate(void)
 
   END_TEST;
 }
+
+int UtcDaliRenderEffectSynchronizeBackgroundCornerRadius(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliRenderEffectSynchronizeBackgroundCornerRadius");
+
+  Integration::Scene scene = application.GetScene();
+
+  Property::Map blackDimmerMap;
+  blackDimmerMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
+  blackDimmerMap.Insert(Toolkit::Visual::Property::MIX_COLOR, Color::BLACK);
+  blackDimmerMap.Insert(Toolkit::Visual::Property::OPACITY, 0.2f);
+  blackDimmerMap.Insert(Toolkit::DevelVisual::Property::CORNER_RADIUS, 30.0f);
+
+  RenderEffect effect = BackgroundBlurEffect::New(0.4f, 40, 10.0f);
+
+  Control control = Control::New();
+  DALI_TEST_CHECK(control.GetRendererCount() == 0u);
+  control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  control.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+  scene.Add(control);
+
+  control.SetProperty(Toolkit::Control::Property::BACKGROUND, blackDimmerMap);
+  DALI_TEST_CHECK(control.GetRendererCount() == 1u);
+  control.SetRenderEffect(effect);
+  DALI_TEST_CHECK(control.GetRendererCount() == 2u);
+
+  Renderer renderer = control.GetRendererAt(1u);
+  Vector4  radius   = Vector4::ZERO;
+  renderer.GetProperty(renderer.GetPropertyIndex(std::string("uRadius"))).Get(radius);
+
+  DALI_TEST_CHECK(radius.x == 30.0f);
+  DALI_TEST_CHECK(radius.y == 30.0f);
+  DALI_TEST_CHECK(radius.z == 30.0f);
+  DALI_TEST_CHECK(radius.w == 30.0f);
+
+  END_TEST;
+}
index 3ff4a2f..fd1dbf8 100644 (file)
@@ -28,6 +28,7 @@
 
 //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>
 
@@ -56,7 +57,6 @@ namespace Internal
 BlurEffectImpl::BlurEffectImpl(bool isBackground)
 : RenderEffectImpl(),
   mInternalRoot(Actor::New()),
-  mPixelFormat(Pixel::Format::INVALID),
   mDownscaleFactor(BLUR_EFFECT_DOWNSCALE_FACTOR),
   mPixelRadius(BLUR_EFFECT_PIXEL_RADIUS),
   mBellCurveWidth(BLUR_EFFECT_BELL_CURVE_WIDTH),
@@ -70,7 +70,6 @@ BlurEffectImpl::BlurEffectImpl(bool isBackground)
 BlurEffectImpl::BlurEffectImpl(float downscaleFactor, uint32_t blurRadius, float bellCurveWidth, bool isBackground)
 : RenderEffectImpl(),
   mInternalRoot(Actor::New()),
-  mPixelFormat(Pixel::Format::INVALID),
   mDownscaleFactor(downscaleFactor),
   mPixelRadius((blurRadius >> 2) + 1),
   mBellCurveWidth(std::max(bellCurveWidth, BLUR_EFFECT_DIVIDE_ZERO_EPSILON)),
@@ -102,8 +101,6 @@ BlurEffectImplPtr BlurEffectImpl::New(float downscaleFactor, uint32_t blurRadius
 
 void BlurEffectImpl::Initialize()
 {
-  RegisterObject(); // of parent's parent class
-
   mRenderFullSizeCamera = CameraActor::New();
   mRenderFullSizeCamera.SetInvertYAxis(true);
   mRenderFullSizeCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
@@ -318,6 +315,11 @@ void BlurEffectImpl::SetShaderConstants(float downsampledWidth, float downsample
     mVerticalBlurActor.RegisterProperty(GetSampleOffsetsPropertyName(i), Vector2(0.0f, uvOffsets[i] / downsampledHeight));
     mVerticalBlurActor.RegisterProperty(GetSampleWeightsPropertyName(i), weights[i]);
   }
+
+  if(mIsBackground)
+  {
+    SynchronizeBackgroundCornerRadius();
+  }
 }
 
 std::string BlurEffectImpl::GetSampleOffsetsPropertyName(unsigned int index) const
@@ -334,6 +336,18 @@ std::string BlurEffectImpl::GetSampleWeightsPropertyName(unsigned int index) con
   return oss.str();
 }
 
+void BlurEffectImpl::SynchronizeBackgroundCornerRadius()
+{
+  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);
+
+  Renderer renderer = GetTargetRenderer();
+  renderer.RegisterProperty("uRadius", radius);
+}
+
 } // namespace Internal
 } // namespace Toolkit
 } // namespace Dali
index eb3fdc2..fe6b177 100644 (file)
@@ -131,6 +131,11 @@ private:
    */
   std::string GetSampleWeightsPropertyName(unsigned int index) const;
 
+  /**
+   * @brief Synchronize mOwnerControl's background corner radius to the blurred output.
+   */
+  void SynchronizeBackgroundCornerRadius();
+
   BlurEffectImpl(const BlurEffectImpl&) = delete;
   BlurEffectImpl(BlurEffectImpl&&)      = delete;
   BlurEffectImpl& operator=(BlurEffectImpl&&) = delete;      // no move()
@@ -155,12 +160,11 @@ private:
   RenderTask  mSourceRenderTask;
 
   // Variables
-  Pixel::Format mPixelFormat;
-  float         mDownscaleFactor;
-  uint32_t      mPixelRadius;
-  float         mBellCurveWidth;
-  float         mMultiplierForFraction;
-  float         mDenominator;
+  float    mDownscaleFactor;
+  uint32_t mPixelRadius;
+  float    mBellCurveWidth;
+  float    mMultiplierForFraction;
+  float    mDenominator;
 
   bool mIsActivated : 1;
   bool mIsBackground : 1;
index ae3a36d..b265985 100644 (file)
@@ -22,9 +22,6 @@
 #include <dali-toolkit/internal/controls/control/control-renderers.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 
-#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
-#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
-
 namespace
 {
 static constexpr float SIZE_STEP_CONDITION = 3.0f;
@@ -51,13 +48,18 @@ void RenderEffectImpl::SetOwnerControl(Dali::Toolkit::Control control)
   if(mOwnerControl)
   {
     mTargetSize = mOwnerControl.GetProperty<Vector2>(Actor::Property::SIZE);
-    mRenderer   = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE);
+    mRenderer   = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG);
 
     mSizeNotification = control.AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION));
     mSizeNotification.NotifySignal().Connect(this, &RenderEffectImpl::OnSizeSet);
   }
 }
 
+Toolkit::Control RenderEffectImpl::GetOwnerControl() const
+{
+  return mOwnerControl;
+}
+
 void RenderEffectImpl::OnSizeSet(PropertyNotification& source)
 {
   mTargetSize = mOwnerControl.GetProperty<Vector2>(Actor::Property::SIZE);
@@ -70,11 +72,6 @@ Renderer RenderEffectImpl::GetTargetRenderer() const
   return mRenderer;
 }
 
-Toolkit::Control RenderEffectImpl::GetOwnerControl() const
-{
-  return mOwnerControl;
-}
-
 Vector2 RenderEffectImpl::GetTargetSize() const
 {
   return mTargetSize;
diff --git a/dali-toolkit/internal/graphics/shaders/render-effect.frag b/dali-toolkit/internal/graphics/shaders/render-effect.frag
new file mode 100644 (file)
index 0000000..95ecb8c
--- /dev/null
@@ -0,0 +1,62 @@
+precision highp float;
+varying highp vec2 vFragCoord;
+varying highp vec2 vTexCoord;
+uniform highp vec3 uSize;
+uniform sampler2D sTexture;
+uniform highp vec4 uRadius;
+
+highp float nrand(const in vec2 uv)
+{
+  const highp float a = 12.9898, b = 78.233, c = 43758.5453, pi = 3.141592653589793;
+  highp float dt = dot(uv, vec2(a, b)), sn = mod(dt, pi);
+  return fract(sin(sn) * c);
+}
+
+vec3 applyDithering( vec3 inColor )
+{
+  float rnd = nrand(vTexCoord) - 0.5;
+  inColor.rgb += rnd / 255.0;
+  return inColor;
+}
+
+// from https://iquilezles.org/articles/distfunctions
+float roundedBoxSDF(vec2 PixelPositionFromCenter, vec2 RectangleEdgePositionFromCenter, float Radius) {
+    return length(max(abs(PixelPositionFromCenter)
+                      - RectangleEdgePositionFromCenter
+                      + Radius
+                      ,0.0))
+           - 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 edgeSoftness = 1.0;
+  float distance = roundedBoxSDF(vFragCoord.xy - (uSize.xy/2.0), uSize.xy/2.0, getCurrentRadius());
+
+  float smoothedAlpha = 1.0 - smoothstep(0.0, edgeSoftness * 2.0, distance);
+  gl_FragColor.a *= smoothedAlpha;
+
+  gl_FragColor.rgb = applyDithering(gl_FragColor.rgb);
+}
diff --git a/dali-toolkit/internal/graphics/shaders/render-effect.vert b/dali-toolkit/internal/graphics/shaders/render-effect.vert
new file mode 100644 (file)
index 0000000..2de4f92
--- /dev/null
@@ -0,0 +1,14 @@
+precision highp float;
+attribute highp vec2 aPosition;
+varying highp vec2 vFragCoord;
+varying highp vec2 vTexCoord;
+uniform highp mat4 uMvpMatrix;
+uniform highp vec3 uSize;
+
+void main()
+{
+  highp vec4 vertexPosition = vec4(aPosition * uSize.xy, 0.0, 1.0);
+  vFragCoord = vertexPosition.xy + uSize.xy/2.0;
+  vTexCoord = aPosition + vec2(0.5);
+  gl_Position = uMvpMatrix * vertexPosition;
+}
index 804c8e2..9964e13 100644 (file)
@@ -25,7 +25,6 @@ namespace Dali
 {
 namespace Toolkit
 {
-
 RenderEffect::RenderEffect(const RenderEffect& handle)
 : BaseHandle(handle)
 {
@@ -37,6 +36,5 @@ RenderEffect::RenderEffect(Internal::RenderEffectImpl* renderEffectImpl)
 }
 
 RenderEffect::~RenderEffect() = default;
-
 } // namespace Toolkit
 } // namespace Dali