BlendMode::ON_WITHOUT_CULL bug fix 04/264704/4
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 28 Sep 2021 10:14:42 +0000 (19:14 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 29 Sep 2021 12:14:14 +0000 (21:14 +0900)
When we set BORDERLINE_WIDTH property on initialize time, mNeedBorderline still false.
So after animate CORER_RADIUS, BlendMode become ON so it will culled when MIX_COLOR.a is zero.
This patch fix that case bug

Change-Id: I3570d17273e6924f934dfc7e8b8fe6910ac18c0b
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp

index bd389ad0f9da3d7a71bac0026586fd7c1b2c61e8..d1a2e56ae8e314b69044b29b1a909f89eac1b5a8 100644 (file)
@@ -4352,6 +4352,242 @@ int UtcDaliVisualBorderline(void)
   END_TEST;
 }
 
+int UtcDaliVisualBorderlineBlendModeTest(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualBorderlineBlendModeTest" );
+  VisualFactory factory = VisualFactory::Get();
+
+  // Case 1 : Test which doesn't support borderline feature.
+  {
+    tet_printf("Test Unsupported visual type\n");
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::BORDER);
+    propertyMap.Insert(BorderVisual::Property::COLOR, Color::BLUE);
+    propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, 1.0f);
+    Visual::Base borderVisual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, borderVisual );
+    actor.SetProperty( Actor::Property::SIZE, Vector2( 2000.f, 2000.f ) );
+    actor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
+    application.GetScene().Add(actor);
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    Renderer renderer = actor.GetRendererAt(0);
+
+    Property::Value blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // Visual::BORDER doesn't support BORDERLINE. BlendMode is AUTO.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::AUTO, TEST_LOCATION );
+
+    application.GetScene().Remove(actor);
+  }
+
+  // Case 2 : Test which support borderline feature.
+  {
+    tet_printf("Test normal case\n");
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+    propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+    propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, 1.0f);
+    Visual::Base colorVisual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, colorVisual );
+    actor.SetProperty( Actor::Property::SIZE, Vector2( 2000.f, 2000.f ) );
+    actor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
+    application.GetScene().Add(actor);
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    Renderer renderer = actor.GetRendererAt(0);
+
+    Property::Value blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // Visual::COLOR support BORDERLINE. BlendMode is ON_WITHOUT_CULL.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::ON_WITHOUT_CULL, TEST_LOCATION );
+
+    application.GetScene().Remove(actor);
+  }
+
+  // Case 3 : Test which animated borderline.
+  {
+    tet_printf("Test borderline animate case\n");
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+    propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+    Visual::Base colorVisual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, colorVisual );
+    actor.SetProperty( Actor::Property::SIZE, Vector2( 2000.f, 2000.f ) );
+    actor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
+    application.GetScene().Add(actor);
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    Renderer renderer = actor.GetRendererAt(0);
+
+    Property::Value blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // BlendMode is AUTO.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::AUTO, TEST_LOCATION );
+
+    Animation animation = Animation::New(0.1f);
+    animation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::BORDERLINE_WIDTH), 1.0f );
+    animation.Play();
+
+    application.SendNotification();
+    application.Render();
+    application.Render(101u); // End of animation
+
+    blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // BlendMode is ON_WITHOUT_CULL.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::ON_WITHOUT_CULL, TEST_LOCATION );
+
+    Animation revanimation = Animation::New(0.1f);
+    revanimation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::BORDERLINE_WIDTH), 0.0f );
+    revanimation.Play();
+
+    application.SendNotification();
+    application.Render();
+    application.Render(101u); // End of animation
+
+    blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // BlendMode is still ON_WITHOUT_CULL.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::ON_WITHOUT_CULL, TEST_LOCATION );
+
+    application.GetScene().Remove(actor);
+  }
+
+  // Case 4 : Test which animated corner radius occur.
+  {
+    tet_printf("Test borderline animate case\n");
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+    propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+    propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, 1.0f);
+    Visual::Base colorVisual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, colorVisual );
+    actor.SetProperty( Actor::Property::SIZE, Vector2( 2000.f, 2000.f ) );
+    actor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
+    application.GetScene().Add(actor);
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    Renderer renderer = actor.GetRendererAt(0);
+
+    Property::Value blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // BlendMode is ON_WITHOUT_CULL.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::ON_WITHOUT_CULL, TEST_LOCATION );
+
+    Animation animation = Animation::New(0.1f);
+    animation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), Vector4(1.0f, 1.0f, 1.0f, 1.0f) );
+    animation.Play();
+
+    application.SendNotification();
+    application.Render();
+    application.Render(101u); // End of animation
+
+    blendModeValue = renderer.GetProperty( Renderer::Property::BLEND_MODE );
+    // BlendMode is ON_WITHOUT_CULL.
+    DALI_TEST_EQUALS( blendModeValue.Get<int>(), (int)BlendMode::ON_WITHOUT_CULL, TEST_LOCATION );
+
+    application.GetScene().Remove(actor);
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualBorderlineColorAnimateTest(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualBorderlineColorAnimateTest color" );
+
+  TestGraphicsController& graphics = application.GetGraphicsController();
+  static std::vector<UniformData> customUniforms =
+  {
+    UniformData("mixColor", Property::Type::VECTOR3),
+    UniformData("cornerRadius", Property::Type::VECTOR4),
+    UniformData("cornerRadiusPolicy", Property::Type::FLOAT),
+    UniformData("borderlineWidth", Property::Type::FLOAT),
+    UniformData("borderlineColor", Property::Type::VECTOR4),
+    UniformData("borderlineOffset", Property::Type::FLOAT),
+  };
+  graphics.AddCustomUniforms(customUniforms);
+
+  {
+    const Vector3 INITIAL_MIX_COLOR( 1.0f,0.0f,1.0f );
+    const float   INITIAL_MIX_OPACITY( 0.5f );
+    const Vector4 INITIAL_BORDERLINE_COLOR( 0.0f,1.0f,0.0f,1.0f );
+    const float   INITIAL_ACTOR_OPACITY( 1.0f );
+    const Vector3 TARGET_MIX_COLOR( 1.0f, 0.0f, 0.0f );
+    const float   TARGET_MIX_OPACITY( 0.8f );
+    const Vector4 TARGET_BORDERLINE_COLOR( 1.0f, 0.0f, 1.0f, 0.2f);
+    const float   TARGET_ACTOR_OPACITY( 0.5f );
+
+    VisualFactory factory = VisualFactory::Get();
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
+    propertyMap.Insert(Visual::Property::MIX_COLOR, INITIAL_MIX_COLOR);
+    propertyMap.Insert(Visual::Property::OPACITY, INITIAL_MIX_OPACITY);
+    propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, 1.0f);
+    propertyMap.Insert(DevelVisual::Property::BORDERLINE_COLOR, INITIAL_BORDERLINE_COLOR);
+    Visual::Base visual = factory.CreateVisual( propertyMap );
+
+    DummyControl actor = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+    actor.SetProperty( Actor::Property::SIZE, Vector2( 2000.f, 2000.f ) );
+    actor.SetProperty( Actor::Property::OPACITY, INITIAL_ACTOR_OPACITY );
+    actor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
+    application.GetScene().Add(actor);
+
+    DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+    Animation animation = Animation::New(4.0f);
+    animation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, Visual::Property::MIX_COLOR), TARGET_MIX_COLOR );
+    animation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, Visual::Property::OPACITY), TARGET_MIX_OPACITY);
+    animation.AnimateTo( DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::BORDERLINE_COLOR), TARGET_BORDERLINE_COLOR );
+    animation.AnimateTo( Property(actor, Actor::Property::OPACITY), TARGET_ACTOR_OPACITY);
+    animation.Play();
+
+    TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+
+    application.SendNotification();
+    application.Render(0);
+    application.Render(2000u); // halfway point
+    application.SendNotification();
+
+    Vector3 halfwayMixColor        = (INITIAL_MIX_COLOR        + TARGET_MIX_COLOR       ) * 0.5f;
+    float   halfwayMixOpacity      = (INITIAL_MIX_OPACITY      + TARGET_MIX_OPACITY     ) * 0.5f;
+    Vector4 halfwayBorderlineColor = (INITIAL_BORDERLINE_COLOR + TARGET_BORDERLINE_COLOR) * 0.5f;
+    float   halfwayActorOpacity    = (INITIAL_ACTOR_OPACITY    + TARGET_ACTOR_OPACITY   ) * 0.5f;
+    halfwayMixOpacity *= halfwayActorOpacity;
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector3>("mixColor", halfwayMixColor), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("uColor", Vector4(1.0f, 1.0f, 1.0f, halfwayMixOpacity)), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("uActorColor", Vector4(1.0f, 1.0f, 1.0f, halfwayActorOpacity)), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("borderlineColor", halfwayBorderlineColor), true, TEST_LOCATION );
+
+    application.Render(2001u); // go past end
+    application.SendNotification(); // Trigger signals
+
+    DALI_TEST_EQUALS( actor.GetCurrentProperty< Vector4 >( Actor::Property::COLOR ), Vector4(1.0f, 1.0f, 1.0f, TARGET_ACTOR_OPACITY), TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector3>("mixColor", TARGET_MIX_COLOR), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("uColor", Vector4(1.0f, 1.0f, 1.0f, TARGET_MIX_OPACITY * TARGET_ACTOR_OPACITY) ), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("uActorColor", Vector4(1.0f, 1.0f, 1.0f, TARGET_ACTOR_OPACITY)), true, TEST_LOCATION );
+    DALI_TEST_EQUALS( glAbstraction.CheckUniformValue<Vector4>("borderlineColor", TARGET_BORDERLINE_COLOR ), true, TEST_LOCATION );
+
+    actor.Unparent();
+  }
+
+  END_TEST;
+}
 
 int UtcDaliColorVisualBlurRadius(void)
 {
index 9863364499f51325be4ea2b672fa34399f1e61e9..593eeb696aad1e01506eacaad0f55c635e15736a 100644 (file)
@@ -72,7 +72,7 @@ ColorVisual::ColorVisual(VisualFactoryCache& factoryCache)
 : Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR),
   mBlurRadius(0.0f),
   mBlurRadiusIndex(Property::INVALID_INDEX),
-  mNeedBlurRadius(false)
+  mAlwaysUsingBlurRadius(false)
 {
 }
 
@@ -217,7 +217,7 @@ Shader ColorVisual::GenerateShader() const
 
   bool roundedCorner = IsRoundedCornerRequired();
   bool borderline    = IsBorderlineRequired();
-  bool blur          = !EqualsZero(mBlurRadius) || mNeedBlurRadius;
+  bool blur          = !EqualsZero(mBlurRadius) || mAlwaysUsingBlurRadius;
   int shaderTypeFlag = ColorVisualRequireFlag::DEFAULT;
 
   if(roundedCorner)
@@ -276,9 +276,10 @@ Dali::Property ColorVisual::OnGetPropertyObject(Dali::Property::Key key)
   {
     mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius);
 
-    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+    // Blur is animated now. we always have to use blur feature.
+    mAlwaysUsingBlurRadius = true;
 
-    mNeedBlurRadius = true;
+    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
 
     // Change shader
     UpdateShader();
index 1f2af5cae10d71a1f5d07e73b98502f013b94caa..6ced771106c0032e03818a05fb5d3c34b0b17b8f 100644 (file)
@@ -131,9 +131,9 @@ private:
   ColorVisual& operator=(const ColorVisual& colorRenderer);
 
 private:
-  float           mBlurRadius;      ///< The blur radius
-  Property::Index mBlurRadiusIndex; ///< The blur radius property index
-  bool            mNeedBlurRadius;  ///< Whether we need the blur radius in shader.
+  float           mBlurRadius;                ///< The blur radius
+  Property::Index mBlurRadiusIndex;           ///< The blur radius property index
+  bool            mAlwaysUsingBlurRadius : 1; ///< Whether we need the blur radius in shader always.
 };
 
 } // namespace Internal
index 53b5246b171faa1e45bed90a5bc1d9f81e569da1..8106899457f3b39b4e47239cf0eb0db3f0803688 100644 (file)
@@ -134,8 +134,8 @@ Internal::Visual::Base::Impl::Impl(FittingMode fittingMode, Toolkit::Visual::Typ
   mFlags(0),
   mResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
   mType(type),
-  mNeedCornerRadius(false),
-  mNeedBorderline(false)
+  mAlwaysUsingBorderline(false),
+  mAlwaysUsingCornerRadius(false)
 {
 }
 
index 52e0d98b6f765561c3961be57f4781af9407b4d1..64ab52f1e63a0f300dea94eb34fe183a45bf64be 100644 (file)
@@ -134,12 +134,12 @@ struct Base::Impl
   Property::Index                 mBorderlineColorIndex;
   Property::Index                 mBorderlineOffsetIndex;
   Property::Index                 mCornerRadiusIndex;
-  FittingMode                     mFittingMode; //< How the contents should fit the view
+  FittingMode                     mFittingMode; ///< How the contents should fit the view
   int                             mFlags;
   Toolkit::Visual::ResourceStatus mResourceStatus;
   const Toolkit::Visual::Type     mType;
-  bool                            mNeedCornerRadius;
-  bool                            mNeedBorderline;
+  bool                            mAlwaysUsingBorderline : 1;   ///< Whether we need the borderline in shader always.
+  bool                            mAlwaysUsingCornerRadius : 1; ///< Whether we need the corner radius in shader always.
 };
 
 } // namespace Visual
index f518895528cd14bce81e41e6d61ac2982909fada..1911b95565fc14e825f16b9df63cdd4f5b868b91 100644 (file)
@@ -583,7 +583,7 @@ bool Visual::Base::IsRoundedCornerRequired() const
       // Update values from Renderer
       mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<Vector4>(mImpl->mCornerRadiusIndex);
     }
-    return !(mImpl->mCornerRadius == Vector4::ZERO) || mImpl->mNeedCornerRadius;
+    return !(mImpl->mCornerRadius == Vector4::ZERO) || mImpl->mAlwaysUsingCornerRadius;
   }
   return false;
 }
@@ -598,7 +598,7 @@ bool Visual::Base::IsBorderlineRequired() const
       // Update values from Renderer
       mImpl->mBorderlineWidth = mImpl->mRenderer.GetProperty<float>(mImpl->mBorderlineWidthIndex);
     }
-    return !EqualsZero(mImpl->mBorderlineWidth) || mImpl->mNeedBorderline;
+    return !EqualsZero(mImpl->mBorderlineWidth) || mImpl->mAlwaysUsingBorderline;
   }
   return false;
 }
@@ -968,7 +968,9 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
       mImpl->mBorderlineWidthIndex  = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_WIDTH, BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
       mImpl->mBorderlineColorIndex  = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_COLOR, BORDERLINE_COLOR, mImpl->mBorderlineColor);
       mImpl->mBorderlineOffsetIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_OFFSET, BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
-      mImpl->mNeedBorderline        = true;
+
+      // Borderline is animated now. we always have to use borderline feature.
+      mImpl->mAlwaysUsingBorderline = true;
 
       index = mImpl->mRenderer.GetPropertyIndex(key);
 
@@ -981,14 +983,16 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key)
       mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::CORNER_RADIUS, CORNER_RADIUS, mImpl->mCornerRadius);
       mImpl->mRenderer.RegisterProperty(CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
 
-      if(!mImpl->mNeedBorderline)
+      // ConerRadius is animated now. we always have to use corner radius feature.
+      mImpl->mAlwaysUsingCornerRadius = true;
+
+      if(!IsBorderlineRequired())
       {
         // If mNeedBorderline is true, BLEND_MODE is already BlendMode::ON_WITHOUT_CULL. So we don't overwrite it.
         mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
       }
 
-      index                    = mImpl->mCornerRadiusIndex;
-      mImpl->mNeedCornerRadius = true;
+      index = mImpl->mCornerRadiusIndex;
 
       // Change shader
       UpdateShader();