From abf5d9bb2bc8c3db867355573bdf8c27389dcf23 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 28 Sep 2021 19:14:42 +0900 Subject: [PATCH] BlendMode::ON_WITHOUT_CULL bug fix 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 --- .../src/dali-toolkit/utc-Dali-Visual.cpp | 236 +++++++++++++++++++++ .../internal/visuals/color/color-visual.cpp | 9 +- dali-toolkit/internal/visuals/color/color-visual.h | 6 +- .../internal/visuals/visual-base-data-impl.cpp | 4 +- .../internal/visuals/visual-base-data-impl.h | 6 +- dali-toolkit/internal/visuals/visual-base-impl.cpp | 16 +- 6 files changed, 259 insertions(+), 18 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index bd389ad..d1a2e56 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -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(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)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(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)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(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)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)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)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(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)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)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 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(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("mixColor", halfwayMixColor), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("uColor", Vector4(1.0f, 1.0f, 1.0f, halfwayMixOpacity)), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("uActorColor", Vector4(1.0f, 1.0f, 1.0f, halfwayActorOpacity)), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("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("mixColor", TARGET_MIX_COLOR), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("uColor", Vector4(1.0f, 1.0f, 1.0f, TARGET_MIX_OPACITY * TARGET_ACTOR_OPACITY) ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("uActorColor", Vector4(1.0f, 1.0f, 1.0f, TARGET_ACTOR_OPACITY)), true, TEST_LOCATION ); + DALI_TEST_EQUALS( glAbstraction.CheckUniformValue("borderlineColor", TARGET_BORDERLINE_COLOR ), true, TEST_LOCATION ); + + actor.Unparent(); + } + + END_TEST; +} int UtcDaliColorVisualBlurRadius(void) { diff --git a/dali-toolkit/internal/visuals/color/color-visual.cpp b/dali-toolkit/internal/visuals/color/color-visual.cpp index 9863364..593eeb6 100644 --- a/dali-toolkit/internal/visuals/color/color-visual.cpp +++ b/dali-toolkit/internal/visuals/color/color-visual.cpp @@ -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(); diff --git a/dali-toolkit/internal/visuals/color/color-visual.h b/dali-toolkit/internal/visuals/color/color-visual.h index 1f2af5c..6ced771 100644 --- a/dali-toolkit/internal/visuals/color/color-visual.h +++ b/dali-toolkit/internal/visuals/color/color-visual.h @@ -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 diff --git a/dali-toolkit/internal/visuals/visual-base-data-impl.cpp b/dali-toolkit/internal/visuals/visual-base-data-impl.cpp index 53b5246..8106899 100644 --- a/dali-toolkit/internal/visuals/visual-base-data-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-data-impl.cpp @@ -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) { } diff --git a/dali-toolkit/internal/visuals/visual-base-data-impl.h b/dali-toolkit/internal/visuals/visual-base-data-impl.h index 52e0d98..64ab52f 100644 --- a/dali-toolkit/internal/visuals/visual-base-data-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-data-impl.h @@ -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 diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index f518895..1911b95 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -583,7 +583,7 @@ bool Visual::Base::IsRoundedCornerRequired() const // Update values from Renderer mImpl->mCornerRadius = mImpl->mRenderer.GetProperty(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(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(); -- 2.7.4