From: Eunki, Hong Date: Fri, 10 Dec 2021 06:45:14 +0000 (+0900) Subject: DoAction can chage CornerRadius/Borderline/BlurRadius X-Git-Tag: dali_2.1.3~6 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=65ad9904d1df16ac5406fc316265c8f0388f0088 DoAction can chage CornerRadius/Borderline/BlurRadius we can update properies by DoAction(DevelVisual::Action::UPDATE_PROPERTY). It is not an usual case, but we may need to prepare of NUI code fix. (There is some related issue at NUI ImageView) Here, I update some properies that need to update shader. We don't want to change the shader many times. (ex : DoAction with CornerRadius = 1.0f, and DoAction 0.0f after that, and repeat.) So if someone update properies by DoAction API, turn on mAlwaysUseXXX = true so shader will not be previous shader anymore. (This is same logic when these properies are animated.) Change-Id: I963930f261982d50bd647e4ba7ed4e476dd8898d 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 d1a2e56..387275d 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -5446,4 +5447,667 @@ int UtcDaliVisualGetVisualProperty07(void) #endif END_TEST; +} + +int UtcDaliVisualUpdateProperty(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualUpdateProperty: Test update property by DoAction. Standard case" ); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap[Visual::Property::TYPE] = Visual::Type::IMAGE; + propertyMap[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + propertyMap[Visual::Property::MIX_COLOR] = Color::BLUE; + propertyMap[DevelVisual::Property::VISUAL_FITTING_MODE] = DevelVisual::FIT_WIDTH; + + 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(); + + Property::Map originalMap; + imageVisual.CreatePropertyMap( originalMap ); + + float targetOpacity = 0.5f; + Vector3 targetMixColor = Vector3(1.0f, 0.4f, 0.2f); + bool targetPreMultipliedAlpha = originalMap[Visual::Property::PREMULTIPLIED_ALPHA].Get() ^ true; + DevelVisual::FittingMode targetVisualFittingMode = DevelVisual::CENTER; + + Property::Map targetPropertyMap; + targetPropertyMap[Visual::Property::OPACITY] = targetOpacity; + targetPropertyMap[ImageVisual::Property::URL] = "foobar"; + targetPropertyMap[Visual::Property::MIX_COLOR] = targetMixColor; + targetPropertyMap[Visual::Property::PREMULTIPLIED_ALPHA] = targetPreMultipliedAlpha; + targetPropertyMap[DevelVisual::Property::VISUAL_FITTING_MODE] = targetVisualFittingMode; + + // Update Properties + 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* colorValue = resultMap.Find(Visual::Property::MIX_COLOR, Property::VECTOR4); + DALI_TEST_CHECK(colorValue); + DALI_TEST_EQUALS(colorValue->Get(), Vector4(targetMixColor.r, targetMixColor.g, targetMixColor.b, targetOpacity), TEST_LOCATION); + + Property::Value* urlValue = resultMap.Find(ImageVisual::Property::URL, Property::STRING); + DALI_TEST_CHECK(urlValue); + // NOTE : ImageVisual URL must NOT changed. + DALI_TEST_EQUALS(urlValue->Get< std::string >(), TEST_IMAGE_FILE_NAME, TEST_LOCATION); + + Property::Value* preMultipliedValue = resultMap.Find(Visual::Property::PREMULTIPLIED_ALPHA, Property::BOOLEAN); + DALI_TEST_CHECK(preMultipliedValue); + DALI_TEST_EQUALS(preMultipliedValue->Get< bool >(), targetPreMultipliedAlpha, TEST_LOCATION); + + Property::Value* visualFittingModeValue = resultMap.Find(DevelVisual::Property::VISUAL_FITTING_MODE, Property::STRING); + DALI_TEST_CHECK(visualFittingModeValue); + DALI_TEST_EQUALS(visualFittingModeValue->Get< std::string >(), "CENTER", TEST_LOCATION); + + END_TEST; +} + +int UtcDaliVisualUpdatePropertyChangeShader01(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualUpdatePropertyChangeShader01: Test update property by DoAction. 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; + + 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(1.0f, 12.0f, 2.0f, 21.0f); + + Property::Map targetPropertyMap; + targetPropertyMap[DevelVisual::Property::CORNER_RADIUS] = targetCornerRadius; + targetPropertyMap[DevelVisual::Property::CORNER_RADIUS_POLICY] = Toolkit::Visual::Transform::Policy::RELATIVE; + + // 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::RELATIVE), 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 ); + 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 ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + // Shader changed + DALI_TEST_CHECK( callStack.FindMethod("CreateShader") ); + callStack.Reset(); + callStack.Enable(true); + + float targetBorderlineWidth = 10.0f; + Vector4 targetBorderlineColor = Vector4(1.0f, 0.2f, 0.1f, 0.5f); + float targetBorderlineOffset = -0.3f; + + Property::Map targetPropertyMap2; + targetPropertyMap2[DevelVisual::Property::CORNER_RADIUS] = Vector4::ZERO; + targetPropertyMap2[DevelVisual::Property::CORNER_RADIUS_POLICY] = Toolkit::Visual::Transform::Policy::ABSOLUTE; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_WIDTH] = targetBorderlineWidth; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_COLOR] = targetBorderlineColor; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_OFFSET] = targetBorderlineOffset; + + // Update Properties with Borderline + DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap2); + + Property::Map resultMap2; + imageVisual.CreatePropertyMap( resultMap2 ); + + // Test property values: they should be updated + cornerRadiusValue = resultMap2.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); + DALI_TEST_CHECK(cornerRadiusValue); + DALI_TEST_EQUALS(cornerRadiusValue->Get(), Vector4::ZERO, TEST_LOCATION); + + cornerRadiusPolicyValue = resultMap2.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 = resultMap2.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT); + DALI_TEST_CHECK(borderlineWidthValue); + DALI_TEST_EQUALS(borderlineWidthValue->Get(), targetBorderlineWidth, TEST_LOCATION); + + Property::Value* borderlineColorValue = resultMap2.Find(DevelVisual::Property::BORDERLINE_COLOR, Property::VECTOR4); + DALI_TEST_CHECK(borderlineColorValue); + DALI_TEST_EQUALS(borderlineColorValue->Get(), targetBorderlineColor, TEST_LOCATION); + + Property::Value* borderlineOffsetValue = resultMap2.Find(DevelVisual::Property::BORDERLINE_OFFSET, Property::FLOAT); + DALI_TEST_CHECK(borderlineOffsetValue); + DALI_TEST_EQUALS(borderlineOffsetValue->Get(), targetBorderlineOffset, 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") ); + callStack.Reset(); + callStack.Enable(true); + + Property::Map targetPropertyMap3; + targetPropertyMap3[DevelVisual::Property::CORNER_RADIUS] = Vector4::ZERO; + targetPropertyMap3[DevelVisual::Property::CORNER_RADIUS_POLICY] = Toolkit::Visual::Transform::Policy::ABSOLUTE; + targetPropertyMap3[DevelVisual::Property::BORDERLINE_WIDTH] = 0.0f; + targetPropertyMap3[DevelVisual::Property::BORDERLINE_COLOR] = Vector4::ZERO; + targetPropertyMap3[DevelVisual::Property::BORDERLINE_OFFSET] = 0.0f; + + // Update Properties into zero + DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap3); + + Property::Map resultMap3; + imageVisual.CreatePropertyMap( resultMap3 ); + + // Test property values: they should be updated + cornerRadiusValue = resultMap3.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); + DALI_TEST_CHECK(cornerRadiusValue); + DALI_TEST_EQUALS(cornerRadiusValue->Get(), Vector4::ZERO, TEST_LOCATION); + + cornerRadiusPolicyValue = resultMap3.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); + + borderlineWidthValue = resultMap3.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT); + DALI_TEST_CHECK(borderlineWidthValue); + DALI_TEST_EQUALS(borderlineWidthValue->Get(), 0.0f, TEST_LOCATION); + + borderlineColorValue = resultMap3.Find(DevelVisual::Property::BORDERLINE_COLOR, Property::VECTOR4); + DALI_TEST_CHECK(borderlineColorValue); + DALI_TEST_EQUALS(borderlineColorValue->Get(), Vector4::ZERO, TEST_LOCATION); + + borderlineOffsetValue = resultMap3.Find(DevelVisual::Property::BORDERLINE_OFFSET, Property::FLOAT); + DALI_TEST_CHECK(borderlineOffsetValue); + DALI_TEST_EQUALS(borderlineOffsetValue->Get(), 0.0f, 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) ); + // Note : mAlwaysUsingBorderline and mAlwaysUsingCornerRadius is true. + 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) ); + // Note : mAlwaysUsingBorderline and mAlwaysUsingCornerRadius is true. + 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 ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + // Shader not changed + DALI_TEST_CHECK( !callStack.FindMethod("CreateShader") ); + + END_TEST; +} + +int UtcDaliVisualUpdatePropertyChangeShader02(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualUpdatePropertyChangeShader02: Test update property by DoAction. Fake update" ); + + 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; + + 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 ); + } + + Vector4 targetCornerRadius = Vector4(0.0f, 0.0f, 0.0f, 0.0f); + + Property::Map targetPropertyMap; + targetPropertyMap[DevelVisual::Property::CORNER_RADIUS] = targetCornerRadius; + + callStack.Reset(); + callStack.Enable(true); + + // 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); + + // 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 : corner radius is zero. so we don't change shader! + 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 : corner radius is zero. so we don't change shader! + 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 doesn't changed + DALI_TEST_CHECK( !(callStack.FindMethod("CreateShader")) ); + callStack.Reset(); + callStack.Enable(true); + + float targetBorderlineWidth = 0.0f; + Vector4 targetBorderlineColor = Vector4(1.0f, 1.0f, 0.0f, 0.0f); + float targetBorderlineOffset = -1.0f; + + Property::Map targetPropertyMap2; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_WIDTH] = targetBorderlineWidth; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_COLOR] = targetBorderlineColor; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_OFFSET] = targetBorderlineOffset; + + // Update Properties with Borderline + DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap2); + + Property::Map resultMap2; + imageVisual.CreatePropertyMap( resultMap2 ); + + // Test property values: they should be updated + Property::Value* borderlineWidthValue = resultMap2.Find(DevelVisual::Property::BORDERLINE_WIDTH, Property::FLOAT); + DALI_TEST_CHECK(borderlineWidthValue); + DALI_TEST_EQUALS(borderlineWidthValue->Get(), targetBorderlineWidth, TEST_LOCATION); + + Property::Value* borderlineColorValue = resultMap2.Find(DevelVisual::Property::BORDERLINE_COLOR, Property::VECTOR4); + DALI_TEST_CHECK(borderlineColorValue); + DALI_TEST_EQUALS(borderlineColorValue->Get(), targetBorderlineColor, TEST_LOCATION); + + Property::Value* borderlineOffsetValue = resultMap2.Find(DevelVisual::Property::BORDERLINE_OFFSET, Property::FLOAT); + DALI_TEST_CHECK(borderlineOffsetValue); + DALI_TEST_EQUALS(borderlineOffsetValue->Get(), targetBorderlineOffset, 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) ); + // Note : borderline width is zero. so we don't change shader! + 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) ); + // Note : borderline width is zero. so we don't change shader! + 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 ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + + // Shader doesn't changed + DALI_TEST_CHECK( !(callStack.FindMethod("CreateShader")) ); + + END_TEST; +} + +int UtcDaliVisualUpdatePropertyChangeShader03(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualUpdatePropertyChangeShader03: Test update property by DoAction. Blur Radius" ); + + TraceCallStack& callStack = application.GetGraphicsController().mCallStack; + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + // Case ImageVisual + propertyMap[Visual::Property::TYPE] = Visual::Type::COLOR; + propertyMap[ColorVisual::Property::MIX_COLOR] = Color::BLUE; + + 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(); + + 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_BLUR 1") == std::string::npos ); + 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_BLUR 1") == std::string::npos ); + 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 ); + } + + float targetBlurRadius = 15.0f; + Vector4 targetCornerRadius = Vector4(1.0f, 0.1f, 1.1f, 0.0f); + + Property::Map targetPropertyMap; + targetPropertyMap[DevelColorVisual::Property::BLUR_RADIUS] = targetBlurRadius; + targetPropertyMap[DevelVisual::Property::CORNER_RADIUS] = targetCornerRadius; + targetPropertyMap[DevelVisual::Property::BORDERLINE_WIDTH] = 10.0f; // Don't care. just dummy + + callStack.Reset(); + callStack.Enable(true); + + // 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* blurRadiusValue = resultMap.Find(DevelColorVisual::Property::BLUR_RADIUS, Property::FLOAT); + DALI_TEST_CHECK(blurRadiusValue); + DALI_TEST_EQUALS(blurRadiusValue->Get(), targetBlurRadius, TEST_LOCATION); + + Property::Value* cornerRadiusValue = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); + DALI_TEST_CHECK(cornerRadiusValue); + DALI_TEST_EQUALS(cornerRadiusValue->Get(), targetCornerRadius, 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_BLUR 1") != std::string::npos ); + // Note : We ignore borderline when blur radius occured + 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_BLUR 1") != std::string::npos ); + // Note : We ignore borderline when blur radius occured + 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 ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + + // Shader changed + DALI_TEST_CHECK( (callStack.FindMethod("CreateShader")) ); + callStack.Reset(); + callStack.Enable(true); + + Property::Map targetPropertyMap2; + targetPropertyMap2[DevelColorVisual::Property::BLUR_RADIUS] = 0.0f; + targetPropertyMap2[DevelVisual::Property::CORNER_RADIUS] = Vector4::ZERO; + targetPropertyMap2[DevelVisual::Property::BORDERLINE_WIDTH] = 15.0f; // Don't care. just dummy + + // Update Properties with CornerRadius + DevelControl::DoAction(dummyControl, DummyControl::Property::TEST_VISUAL, DevelVisual::Action::UPDATE_PROPERTY, targetPropertyMap2); + + Property::Map resultMap2; + imageVisual.CreatePropertyMap( resultMap2 ); + + // Test property values: they should be updated + blurRadiusValue = resultMap2.Find(DevelColorVisual::Property::BLUR_RADIUS, Property::FLOAT); + DALI_TEST_CHECK(blurRadiusValue); + DALI_TEST_EQUALS(blurRadiusValue->Get(), 0.0f, TEST_LOCATION); + + cornerRadiusValue = resultMap2.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); + DALI_TEST_CHECK(cornerRadiusValue); + DALI_TEST_EQUALS(cornerRadiusValue->Get(), Vector4::ZERO, 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) ); + // Note : mAlwaysUsingBlurRadius and mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( fragmentShader.find("#define IS_REQUIRED_BLUR 1") != std::string::npos ); + // Note : We ignore borderline when blur radius occured + 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) ); + // Note : mAlwaysUsingBlurRadius and mAlwaysUsingCornerRadius is true. + DALI_TEST_CHECK( vertexShader.find("#define IS_REQUIRED_BLUR 1") != std::string::npos ); + // Note : We ignore borderline when blur radius occured + 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 ); + } + + // Send shader compile signal + application.SendNotification(); + application.Render(); + + callStack.Enable(false); + + // Shader not changed + DALI_TEST_CHECK( !(callStack.FindMethod("CreateShader")) ); + + END_TEST; } \ No newline at end of file diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h index 1d21356..ad8b5ac 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -133,7 +133,7 @@ public: // from Visual /** * @copydoc Visual::Base::OnDoAction */ - void OnDoAction(const Dali::Property::Index actionName, const Dali::Property::Value& attributes) override; + void OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) override; protected: /** diff --git a/dali-toolkit/internal/visuals/color/color-visual.cpp b/dali-toolkit/internal/visuals/color/color-visual.cpp index 73b0931..31e0c55 100644 --- a/dali-toolkit/internal/visuals/color/color-visual.cpp +++ b/dali-toolkit/internal/visuals/color/color-visual.cpp @@ -23,6 +23,7 @@ #include //INTERNAL INCLUDES +#include #include #include #include @@ -113,6 +114,27 @@ void ColorVisual::DoSetProperties(const Property::Map& propertyMap) { DALI_LOG_ERROR("ColorVisual:DoSetProperties:: BLUR_RADIUS property has incorrect type: %d\n", blurRadiusValue->GetType()); } + + if(mBlurRadiusIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mBlurRadiusIndex, mBlurRadius); + } + else if(DALI_UNLIKELY(mImpl->mRenderer && (!EqualsZero(mBlurRadius) || mAlwaysUsingBlurRadius))) + { + // Unusual case. SetProperty called after OnInitialize(). + // Assume that DoAction call UPDATE_PROPERTY. + // We must regist properies into renderer, and update shader. + + // BlurRadius added by this action. Regist property to renderer. + mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius); + mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON); + + // Change the shader must not be occured many times. we always have to use blur feature. + mAlwaysUsingBlurRadius = true; + + // Change shader + UpdateShader(); + } } } diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index b798e57..7676bf8 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -795,11 +795,11 @@ void ImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const } } -void ImageVisual::OnDoAction(const Dali::Property::Index actionName, const Dali::Property::Value& attributes) +void ImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) { // Check if action is valid for this visual type and perform action if possible - switch(actionName) + switch(actionId) { case DevelImageVisual::Action::RELOAD: { diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index c0a3f75..55fb59b 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -171,7 +171,7 @@ public: // from Visual /** * @copydoc Visual::Base::OnDoAction */ - void OnDoAction(const Dali::Property::Index actionName, const Dali::Property::Value& attributes) override; + void OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) override; protected: /** diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index f0a7af4..2841655 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -168,6 +168,7 @@ void Visual::Base::SetCustomShader(const Property::Map& shaderMap) void Visual::Base::SetProperties(const Property::Map& propertyMap) { + bool needUpdateShader = false; for(size_t i = 0; i < propertyMap.Count(); ++i) { const KeyValuePair& pair = propertyMap.GetKeyValue(i); @@ -300,6 +301,26 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap) { mImpl->mRenderer.SetProperty(mImpl->mBorderlineWidthIndex, mImpl->mBorderlineWidth); } + else if(DALI_UNLIKELY(mImpl->mRenderer && IsBorderlineRequired())) + { + // Unusual case. SetProperty called after OnInitialize(). + // Assume that DoAction call UPDATE_PROPERTY. + // We must regist properies into renderer, and update shader. + + // Borderline added by this action. Regist property to renderer. + 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); + + // Make Blend mode ON_WITHOUT_CULL for transparent mix color. + mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL); + + // Change the shader must not be occured many times. we always have to use borderline feature. + mImpl->mAlwaysUsingBorderline = true; + + // Change shader + needUpdateShader = true; + } break; } case Toolkit::DevelVisual::Property::BORDERLINE_COLOR: @@ -358,6 +379,28 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap) { mImpl->mRenderer.SetProperty(mImpl->mCornerRadiusIndex, mImpl->mCornerRadius); } + else if(DALI_UNLIKELY(mImpl->mRenderer && IsRoundedCornerRequired())) + { + // Unusual case. SetProperty called after OnInitialize(). + // Assume that DoAction call UPDATE_PROPERTY. + // We must regist properies into renderer, and update shader. + + // CornerRadius added by this action. Regist property to renderer. + mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::CORNER_RADIUS, CORNER_RADIUS, mImpl->mCornerRadius); + mImpl->mRenderer.RegisterProperty(CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy); + + // Change the shader must not be occured many times. we always have to use corner radius feature. + mImpl->mAlwaysUsingCornerRadius = true; + + if(!IsBorderlineRequired()) + { + // If IsBorderlineRequired 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); + } + + // Change shader + needUpdateShader = true; + } break; } case Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY: @@ -371,6 +414,15 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap) case Toolkit::Visual::Transform::Policy::ABSOLUTE: { mImpl->mCornerRadiusPolicy = policy; + if(DALI_UNLIKELY(mImpl->mRenderer && mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)) + { + // Unusual case. SetProperty called after OnInitialize(). + // Assume that DoAction call UPDATE_PROPERTY. + // We must update properies result into renderer + // Note : mImpl->mCornerRadiusIndex is not INVALID_INDEX. + // So CornerRadiusPolicy property is already registed. + mImpl->mRenderer.SetProperty(mImpl->mRenderer.GetPropertyIndex(CORNER_RADIUS_POLICY), mImpl->mCornerRadiusPolicy); + } break; } default: @@ -386,6 +438,11 @@ void Visual::Base::SetProperties(const Property::Map& propertyMap) } DoSetProperties(propertyMap); + + if(DALI_UNLIKELY(needUpdateShader)) + { + UpdateShader(); + } } void Visual::Base::SetTransformAndSize(const Property::Map& transform, Size controlSize) diff --git a/dali-toolkit/internal/visuals/visual-base-impl.h b/dali-toolkit/internal/visuals/visual-base-impl.h index d04d3df..b7b72e1 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-impl.h @@ -92,12 +92,12 @@ public: void SetTransformAndSize(const Property::Map& transform, Size controlSize); /** - * @brief Performs an action on the visual with the given action name and attributes. + * @brief Performs an action on the visual with the given action id and attributes. * - * @param[in] actionName The name of the action to perform this API only takes an Index + * @param[in] actionId The id of the action to perform this API only takes an Index * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) */ - void DoAction(const Dali::Property::Index actionName, const Dali::Property::Value attributes); + void DoAction(const Dali::Property::Index actionId, const Dali::Property::Value attributes); /** * @copydoc Toolkit::Visual::Base::GetHeightForWidth