From: Eunki, Hong Date: Mon, 7 Mar 2022 08:53:05 +0000 (+0900) Subject: Fix shader issue during Animation & UPDATE_PROPERTY action X-Git-Tag: dali_2.1.13~7^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=a13c1413109c30ff1d3b4d12ebe44b6ec84144fe Fix shader issue during Animation & UPDATE_PROPERTY action mAlwaysUsingCornerRadius flag used when corner radius is on animation, or it is updated by UPDATE_PROPERTY action. It is neccessary cause we cannot detemine the value. So, so bad timming, when mCornerRadius is 0.0f and we call UpdateShader, the shader cannot use mCornerRadius feature. There was some bug when mImpl->Renderer already contain CornerRadiusIndex. Normal case, it will not happend because we always re-create visual in that case. but, there also can exist some un-normal case = UPDATE_PROPERTY action. When we setup CornerRadius first, and create Animation corner radius into zero. and after animation finish, DoAction(UPDATE_PROPERTY) with borderline. and animate one more time. In that case, the visual's shader doesn't contain CornerRadius! TODO : We don't care about blur radius currently. NUI didn't do UPDATE_PROPERTY action for this property now. But anyway we should consider him. Change-Id: Idf454ed8693da89d5c2f60d0f6a286dbf98c28ac Signed-off-by: Eunki, Hong --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index 87701b2..aaedd55 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -6110,4 +6110,156 @@ int UtcDaliVisualUpdatePropertyChangeShader03(void) DALI_TEST_CHECK( !(callStack.FindMethod("CreateShader")) ); END_TEST; -} \ No newline at end of file +} + +int UtcDaliVisualUpdatePropertyChangeShader04(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualUpdatePropertyChangeShader04: Test update property by DoAction during Animation. Change the shader case" ); + + TraceCallStack& callStack = application.GetGraphicsController().mCallStack; + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + // Case ImageVisual + propertyMap[Visual::Property::TYPE] = Visual::Type::IMAGE; + propertyMap[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + propertyMap[DevelVisual::Property::CORNER_RADIUS] = 10.0f; + + Visual::Base imageVisual = factory.CreateVisual(propertyMap); + + DummyControl dummyControl = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(dummyControl.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f); + application.GetScene().Add(dummyControl); + + application.SendNotification(); + application.Render(); + + // Wait for image loading + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + // Get shader + { + Renderer renderer = dummyControl.GetRendererAt( 0 ); + Shader shader = renderer.GetShader(); + Property::Value value = shader.GetProperty( Shader::Property::PROGRAM ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + + Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_CHECK( fragment ); + std::string fragmentShader; + DALI_TEST_CHECK( fragment->Get(fragmentShader) ); + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos ); + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + std::string vertexShader; + DALI_TEST_CHECK( vertex->Get(vertexShader) ); + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos ); + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + } + callStack.Reset(); + callStack.Enable(true); + + Vector4 targetCornerRadius = Vector4(0.0f, 0.0f, 0.0f, 0.0f); + + Animation animation = Animation::New(1.0f); + animation.AnimateTo(DevelControl::GetVisualProperty(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Property::CORNER_RADIUS), targetCornerRadius); + animation.Play(); + + application.SendNotification(); + application.Render(); + application.Render(1001u); // End of animation + + // Get shader + { + Renderer renderer = dummyControl.GetRendererAt( 0 ); + Shader shader = renderer.GetShader(); + Property::Value value = shader.GetProperty( Shader::Property::PROGRAM ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + + Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_CHECK( fragment ); + std::string fragmentShader; + DALI_TEST_CHECK( fragment->Get(fragmentShader) ); + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos ); + // Note : mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + std::string vertexShader; + DALI_TEST_CHECK( vertex->Get(vertexShader) ); + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") == std::string::npos ); + // Note : mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + } + callStack.Enable(false); + // Shader not changed + DALI_TEST_CHECK( !callStack.FindMethod("CreateShader") ); + callStack.Reset(); + callStack.Enable(true); + + float targetBorderlineWidth = 10.0f; + Property::Map targetPropertyMap; + targetPropertyMap[DevelVisual::Property::BORDERLINE_WIDTH] = targetBorderlineWidth; + + // Update Properties with CornerRadius + DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap); + + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + // Test property values: they should be updated + Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); + DALI_TEST_CHECK(cornerRadiusValue); + DALI_TEST_EQUALS(cornerRadiusValue->Get(), targetCornerRadius, TEST_LOCATION); + + Property::Value* cornerRadiusPolicyValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS_POLICY, Property::INTEGER); + DALI_TEST_CHECK(cornerRadiusPolicyValue); + DALI_TEST_EQUALS(cornerRadiusPolicyValue->Get(), static_cast(Toolkit::Visual::Transform::Policy::ABSOLUTE), TEST_LOCATION); + + Property::Value* borderlineWidthValue = resultMap.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT); + DALI_TEST_CHECK(borderlineWidthValue); + DALI_TEST_EQUALS(borderlineWidthValue->Get(), targetBorderlineWidth, TEST_LOCATION); + + // Get shader + { + Renderer renderer = dummyControl.GetRendererAt( 0 ); + Shader shader = renderer.GetShader(); + Property::Value value = shader.GetProperty( Shader::Property::PROGRAM ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + + Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_CHECK( fragment ); + std::string fragmentShader; + DALI_TEST_CHECK( fragment->Get(fragmentShader) ); + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BORDERLINE 1") != std::string::npos ); + // Note : mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + std::string vertexShader; + DALI_TEST_CHECK( vertex->Get(vertexShader) ); + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BORDERLINE 1") != std::string::npos ); + // Note : mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_ROUNDED_CORNER 1") != std::string::npos ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + // Shader changed + DALI_TEST_CHECK( callStack.FindMethod("CreateShader") ); + + END_TEST; +} diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 288ed34..81126c3 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -1098,6 +1098,21 @@ Dali::Property Visual::Base::GetPropertyObject(Dali::Property::Key key) return OnGetPropertyObject(key); } } + else + { + if(index == mImpl->mBorderlineWidthIndex || + index == mImpl->mBorderlineColorIndex || + index == mImpl->mBorderlineOffsetIndex) + { + // Borderline is animated now. we always have to use borderline feature. + mImpl->mAlwaysUsingBorderline = true; + } + if(index == mImpl->mCornerRadiusIndex) + { + // CornerRadius is animated now. we always have to use corner radius feature. + mImpl->mAlwaysUsingCornerRadius = true; + } + } return Dali::Property(mImpl->mRenderer, index); }