From 282c2727f7b8a9ed422dcc71b4f3aec79d1df6b2 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 9 Jul 2024 17:58:17 +0900 Subject: [PATCH] Make hole match with Actor size at color visual shader There was some needs that ignore the contents area when we use Shadow. Since visual itself doesn't know the area of view, we should use just uSize and visual itself's corner radius. Change-Id: I1ae6104c9d8260f43230d2949af45c8b244419f6 Signed-off-by: Eunki, Hong --- .../src/dali-toolkit/utc-Dali-Visual.cpp | 119 ++++++++++++++++++++- .../visuals/color-visual-properties-devel.h | 24 ++++- .../graphics/shaders/color-visual-shader.frag | 86 ++++++++++++--- .../graphics/shaders/color-visual-shader.vert | 16 +++ .../internal/visuals/color/color-visual.cpp | 75 ++++++++++--- dali-toolkit/internal/visuals/color/color-visual.h | 16 ++- .../internal/visuals/visual-factory-cache.h | 6 ++ .../internal/visuals/visual-string-constants.cpp | 7 ++ .../internal/visuals/visual-string-constants.h | 1 + 9 files changed, 318 insertions(+), 32 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index e2659ff..252fbba 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -555,6 +555,7 @@ int UtcDaliVisualGetPropertyMap1(void) propertyMap.Insert(DevelVisual::Property::BORDERLINE_COLOR, Color::RED); propertyMap.Insert(DevelVisual::Property::BORDERLINE_OFFSET, -1.0f); propertyMap.Insert(DevelColorVisual::Property::BLUR_RADIUS, 20.0f); + propertyMap.Insert(DevelColorVisual::Property::CUTOUT_POLICY, DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS); Visual::Base colorVisual = factory.CreateVisual(propertyMap); Property::Map resultMap; @@ -592,6 +593,10 @@ int UtcDaliVisualGetPropertyMap1(void) DALI_TEST_CHECK(blurRadiusValue); DALI_TEST_CHECK(blurRadiusValue->Get() == 20.0f); + Property::Value* cutoutPolicyValue = resultMap.Find(DevelColorVisual::Property::CUTOUT_POLICY, Property::INTEGER); + DALI_TEST_CHECK(cutoutPolicyValue); + DALI_TEST_CHECK(cutoutPolicyValue->Get() == DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS); + // change the blend color propertyMap[ColorVisual::Property::MIX_COLOR] = Color::CYAN; colorVisual = factory.CreateVisual(propertyMap); @@ -611,6 +616,35 @@ int UtcDaliVisualGetPropertyMap1(void) DALI_TEST_CHECK(blurRadiusValue); DALI_TEST_CHECK(blurRadiusValue->Get() == 0.0f); + // Test wrong values 2 + propertyMap[DevelColorVisual::Property::CUTOUT_POLICY] = Vector2(2.0f, 3.0f); + + colorVisual = factory.CreateVisual(propertyMap); + colorVisual.CreatePropertyMap(resultMap); + + cutoutPolicyValue = resultMap.Find(DevelColorVisual::Property::CUTOUT_POLICY, Property::INTEGER); + DALI_TEST_CHECK(cutoutPolicyValue); + DALI_TEST_CHECK(cutoutPolicyValue->Get() == DevelColorVisual::CutoutPolicy::NONE); + + // Test property set by string + propertyMap[DevelColorVisual::Property::CUTOUT_POLICY] = "CUTOUT_VIEW"; + + colorVisual = factory.CreateVisual(propertyMap); + colorVisual.CreatePropertyMap(resultMap); + + cutoutPolicyValue = resultMap.Find(DevelColorVisual::Property::CUTOUT_POLICY, Property::INTEGER); + DALI_TEST_CHECK(cutoutPolicyValue); + DALI_TEST_CHECK(cutoutPolicyValue->Get() == DevelColorVisual::CutoutPolicy::CUTOUT_VIEW); + + propertyMap[DevelColorVisual::Property::CUTOUT_POLICY] = "CUTOUT_VIEW_WITH_CORNER_RADIUS"; + + colorVisual = factory.CreateVisual(propertyMap); + colorVisual.CreatePropertyMap(resultMap); + + cutoutPolicyValue = resultMap.Find(DevelColorVisual::Property::CUTOUT_POLICY, Property::INTEGER); + DALI_TEST_CHECK(cutoutPolicyValue); + DALI_TEST_CHECK(cutoutPolicyValue->Get() == DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS); + END_TEST; } @@ -6652,4 +6686,87 @@ int UtcDaliVisualUpdatePropertyChangeShader05(void) application.GetGlAbstraction().mShaderLanguageVersion = originalShaderVersion; END_TEST; -} \ No newline at end of file +} + +int UtcDaliVisualCutoutPolicyChangeShader01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliVisualCutoutPolicyChangeShader01: ColorVisual with cutout policy"); + + static std::vector customUniforms = + { + UniformData("uCutoutWithCornerRadius", Property::Type::INTEGER), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + VisualFactory factory = VisualFactory::Get(); + + // Test (Enable/Disable) CornerRadius, (Enable/Disable) Borderline, (Enable/Disable) Blur, and 3 kind of CutoutPolicy + for(int testCase = 0; testCase < 2 * 2 * 2 * 3; ++testCase) + { + const bool enableCornerRadius = (testCase & 1); + const bool enableBorderline = (testCase & 2); + const bool enableBlur = (testCase & 4); + + // clang-format off + const DevelColorVisual::CutoutPolicy::Type cutoutPolicy = (testCase / 8) == 0 ? DevelColorVisual::CutoutPolicy::NONE : + (testCase / 8) == 1 ? DevelColorVisual::CutoutPolicy::CUTOUT_VIEW : + DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS; + // clang-format on + + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR); + propertyMap.Insert(Visual::Property::MIX_COLOR, Color::BLUE); + if(enableCornerRadius) + { + propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, 10.0f); + propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS_POLICY, Toolkit::Visual::Transform::Policy::RELATIVE); + } + if(enableBorderline) + { + propertyMap.Insert(DevelVisual::Property::BORDERLINE_WIDTH, 20.0f); + propertyMap.Insert(DevelVisual::Property::BORDERLINE_COLOR, Color::RED); + propertyMap.Insert(DevelVisual::Property::BORDERLINE_OFFSET, -1.0f); + } + if(enableBlur) + { + propertyMap.Insert(DevelColorVisual::Property::BLUR_RADIUS, 20.0f); + } + propertyMap.Insert(DevelColorVisual::Property::CUTOUT_POLICY, cutoutPolicy); + + Visual::Base colorVisual = factory.CreateVisual(propertyMap); + + DummyControl dummyControl = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(dummyControl.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, colorVisual); + dummyControl[Actor::Property::SIZE] = Vector2(200.f, 200.f); + application.GetScene().Add(dummyControl); + + application.SendNotification(); + application.Render(); + + TestShaderCodeContainSubstrings( + dummyControl, + { + {"#define IS_REQUIRED_BLUR", enableBlur}, + {"#define IS_REQUIRED_BORDERLINE", !enableBlur && enableBorderline}, ///< Since borderline is ignored, due to blur enabled. + {"#define IS_REQUIRED_ROUNDED_CORNER", enableCornerRadius}, + {"#define IS_REQUIRED_CUTOUT", cutoutPolicy != DevelColorVisual::CutoutPolicy::NONE}, + }, + TEST_LOCATION); + + if(cutoutPolicy != DevelColorVisual::CutoutPolicy::NONE) + { + auto& gl = application.GetGlAbstraction(); + DALI_TEST_EQUALS(gl.CheckUniformValue("uCutoutWithCornerRadius", cutoutPolicy == DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS ? 1 : 0), true, TEST_LOCATION); + } + dummyControl.Unparent(); + + application.SendNotification(); + application.Render(); + } + + END_TEST; +} diff --git a/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h index bae7111..4d5ed48 100644 --- a/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,12 +46,34 @@ enum * @note Optional. * @note The default is 0. * @note The visual size increases by the blur radius. + * @note We cannot use blur radius and borderline properties at the same time. */ BLUR_RADIUS = MIX_COLOR + 2, + + /** + * @brief Policy of cutout the color render result. + * @details Name "cutoutPolicy", type Property::INTEGER. + * @note Optional. + * @note The default is CutoutPolicy::NONE. + */ + CUTOUT_POLICY = MIX_COLOR + 3, }; } // namespace Property +/** + * @brief Enumeration for cutout policy. + */ +namespace CutoutPolicy +{ +enum Type +{ + NONE, ///< Fully render the visual area (Default) + CUTOUT_VIEW, ///< Cutout the area of the view. It will use size of view. + CUTOUT_VIEW_WITH_CORNER_RADIUS, ///< Cutout the area of the view include visual's corner radius. It will use size of view. +}; +} // namespace CutoutPolicy + } // namespace DevelColorVisual } // namespace Toolkit diff --git a/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag b/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag index 735f96b..e9d5c0e 100644 --- a/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag +++ b/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag @@ -7,7 +7,14 @@ INPUT highp float vAliasMargin; INPUT highp vec4 vCornerRadius; #endif #endif +#if defined(IS_REQUIRED_CUTOUT) +INPUT highp vec2 vPositionFromCenter; +#if defined(IS_REQUIRED_ROUNDED_CORNER) +INPUT highp vec4 vCutoutCornerRadius; +#endif +#endif +uniform highp vec3 uSize; uniform lowp vec4 uColor; uniform lowp vec3 mixColor; #ifdef IS_REQUIRED_BLUR @@ -19,6 +26,10 @@ uniform lowp vec4 borderlineColor; uniform lowp vec4 uActorColor; #endif +#if defined(IS_REQUIRED_CUTOUT) +uniform lowp int uCutoutWithCornerRadius; +#endif + #if defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE) || defined(IS_REQUIRED_BLUR) // Global values both rounded corner and borderline use @@ -41,25 +52,25 @@ highp float gMinOutlinePotential = 0.0; highp float gMaxInlinePotential = 0.0; highp float gMinInlinePotential = 0.0; -void calculateCornerRadius() +void calculateCornerRadius(highp vec4 cornerRadius, highp vec2 position) { #ifdef IS_REQUIRED_ROUNDED_CORNER gRadius = mix( - mix(vCornerRadius.x, vCornerRadius.y, sign(vPosition.x) * 0.5 + 0.5), - mix(vCornerRadius.w, vCornerRadius.z, sign(vPosition.x) * 0.5 + 0.5), - sign(vPosition.y) * 0.5 + 0.5 + mix(cornerRadius.x, cornerRadius.y, sign(position.x) * 0.5 + 0.5), + mix(cornerRadius.w, cornerRadius.z, sign(position.x) * 0.5 + 0.5), + sign(position.y) * 0.5 + 0.5 ); #endif } -void calculatePosition() +void calculatePosition(highp vec2 position, highp vec2 halfSizeOfRect, highp float currentBorderlineWidth) { - gFragmentPosition = abs(vPosition) - vRectSize; + gFragmentPosition = abs(position) - halfSizeOfRect; gCenterPosition = -gRadius; #ifdef IS_REQUIRED_BLUR #elif defined(IS_REQUIRED_BORDERLINE) - gCenterPosition += borderlineWidth * (clamp(borderlineOffset, -1.0, 1.0) + 1.0) * 0.5; + gCenterPosition += currentBorderlineWidth * (clamp(borderlineOffset, -1.0, 1.0) + 1.0) * 0.5; #endif gDiff = gFragmentPosition - gCenterPosition; } @@ -69,7 +80,7 @@ void calculatePotential() gPotential = length(max(gDiff, 0.0)) + min(0.0, max(gDiff.x, gDiff.y)); } -void setupMinMaxPotential() +void setupMinMaxPotential(highp float currentBorderlineWidth) { gPotentialRange = vAliasMargin; @@ -80,8 +91,8 @@ void setupMinMaxPotential() gMaxInlinePotential = gMaxOutlinePotential; gMinInlinePotential = gMinOutlinePotential; #elif defined(IS_REQUIRED_BORDERLINE) - gMaxInlinePotential = gMaxOutlinePotential - borderlineWidth; - gMinInlinePotential = gMinOutlinePotential - borderlineWidth; + gMaxInlinePotential = gMaxOutlinePotential - currentBorderlineWidth; + gMinInlinePotential = gMinOutlinePotential - currentBorderlineWidth; #else gMaxInlinePotential = gMaxOutlinePotential; gMinInlinePotential = gMinOutlinePotential; @@ -92,13 +103,13 @@ void setupMinMaxPotential() gMinOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0); } -void PreprocessPotential() +void PreprocessPotential(highp vec4 cornerRadius, highp vec2 position, highp vec2 halfSizeOfRect, highp float currentBorderlineWidth) { - calculateCornerRadius(); - calculatePosition(); + calculateCornerRadius(cornerRadius, position); + calculatePosition(position, halfSizeOfRect, currentBorderlineWidth); calculatePotential(); - setupMinMaxPotential(); + setupMinMaxPotential(currentBorderlineWidth); } #endif @@ -277,6 +288,38 @@ void main() { lowp vec4 targetColor = vec4(mixColor, 1.0) * uColor; +#ifdef IS_REQUIRED_CUTOUT + mediump float discardOpacity = 1.0; + + if(abs(vPositionFromCenter.x) <= uSize.x * 0.5 && abs(vPositionFromCenter.y) <= uSize.y * 0.5) + { +#if defined(IS_REQUIRED_ROUNDED_CORNER) + if(uCutoutWithCornerRadius > 0) + { + // Ignore borderline width + PreprocessPotential(vCutoutCornerRadius, vPositionFromCenter, uSize.xy * 0.5, 0.0); + + // Decrease potential range, to avoid alias make some hole. + gMinOutlinePotential -= gPotentialRange * 0.5; + gMaxOutlinePotential -= gPotentialRange * 0.5; + + discardOpacity = smoothstep(gMinOutlinePotential, gMaxOutlinePotential, gPotential); + } + else + { + discardOpacity = 0.0; + } + + if(discardOpacity < 0.001) + { + discard; + } +#else + discard; +#endif + } +#endif + #if defined(IS_REQUIRED_BLUR) || defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE) // skip most potential calculate for performance if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y) @@ -285,7 +328,16 @@ void main() } else { - PreprocessPotential(); + highp vec4 tempCornerRadius = vec4(0.0); + highp float tempBorderlineWidth = 0.0; +#ifdef IS_REQUIRED_ROUNDED_CORNER + tempCornerRadius = vCornerRadius; +#endif +#ifdef IS_REQUIRED_BLUR +#elif defined(IS_REQUIRED_BORDERLINE) + tempBorderlineWidth = borderlineWidth; +#endif + PreprocessPotential(tempCornerRadius, vPosition, vRectSize, tempBorderlineWidth); #endif #ifdef IS_REQUIRED_BLUR @@ -305,4 +357,8 @@ void main() #if defined(IS_REQUIRED_BLUR) || defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE) } #endif + +#ifdef IS_REQUIRED_CUTOUT + OUT_COLOR.a *= discardOpacity; +#endif } diff --git a/dali-toolkit/internal/graphics/shaders/color-visual-shader.vert b/dali-toolkit/internal/graphics/shaders/color-visual-shader.vert index 29b7442..223de22 100644 --- a/dali-toolkit/internal/graphics/shaders/color-visual-shader.vert +++ b/dali-toolkit/internal/graphics/shaders/color-visual-shader.vert @@ -8,6 +8,12 @@ OUTPUT highp float vAliasMargin; OUTPUT highp vec4 vCornerRadius; #endif #endif +#if defined(IS_REQUIRED_CUTOUT) +OUTPUT highp vec2 vPositionFromCenter; +#if defined(IS_REQUIRED_ROUNDED_CORNER) +OUTPUT highp vec4 vCutoutCornerRadius; +#endif +#endif uniform highp mat4 uMvpMatrix; uniform highp vec3 uSize; @@ -92,7 +98,17 @@ vec4 ComputeVertexPosition() #else highp vec2 vPosition = aPosition * visualSize; #endif + +#if defined(IS_REQUIRED_CUTOUT) + vPositionFromCenter = vPosition + anchorPoint * visualSize + visualOffset + origin * uSize.xy; +#if defined(IS_REQUIRED_ROUNDED_CORNER) + vCutoutCornerRadius = mix(cornerRadius * min(uSize.x, uSize.y), cornerRadius, cornerRadiusPolicy); + vCutoutCornerRadius = min(vCutoutCornerRadius, min(uSize.x, uSize.y) * 0.5); +#endif + return vec4(vPositionFromCenter, 0.0, 1.0); +#else return vec4(vPosition + anchorPoint * visualSize + visualOffset + origin * uSize.xy, 0.0, 1.0); +#endif } void main() diff --git a/dali-toolkit/internal/visuals/color/color-visual.cpp b/dali-toolkit/internal/visuals/color/color-visual.cpp index 10856d3..435eac0 100644 --- a/dali-toolkit/internal/visuals/color/color-visual.cpp +++ b/dali-toolkit/internal/visuals/color/color-visual.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include "color-visual.h" +#include // EXTERNAL INCLUDES #include @@ -24,7 +24,6 @@ #include //INTERNAL INCLUDES -#include #include #include #include @@ -42,16 +41,32 @@ namespace Internal { namespace { -const int CUSTOM_PROPERTY_COUNT(0); +const int CUSTOM_PROPERTY_COUNT(0); ///< Note : cutout policy property will be registered only of the cutout view is used. + ///< We don't need to reserve that property memory always. + +// cutout policies +DALI_ENUM_TO_STRING_TABLE_BEGIN(CUTOUT_POLICY) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelColorVisual::CutoutPolicy, NONE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelColorVisual::CutoutPolicy, CUTOUT_VIEW) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelColorVisual::CutoutPolicy, CUTOUT_VIEW_WITH_CORNER_RADIUS) +DALI_ENUM_TO_STRING_TABLE_END(CUTOUT_POLICY) + +constexpr VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[] = { + VisualFactoryCache::COLOR_SHADER, + VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER, + VisualFactoryCache::COLOR_SHADER_BORDERLINE, + VisualFactoryCache::COLOR_SHADER_ROUNDED_BORDERLINE, + VisualFactoryCache::COLOR_SHADER_BLUR_EDGE, + VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER_BLUR_EDGE, +}; -VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[6] = - { - VisualFactoryCache::COLOR_SHADER, - VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER, - VisualFactoryCache::COLOR_SHADER_BORDERLINE, - VisualFactoryCache::COLOR_SHADER_ROUNDED_BORDERLINE, - VisualFactoryCache::COLOR_SHADER_BLUR_EDGE, - VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER_BLUR_EDGE, +constexpr VisualFactoryCache::ShaderType SHADER_TYPE_WITH_CUTOUT_TABLE[] = { + VisualFactoryCache::COLOR_SHADER_CUTOUT, + VisualFactoryCache::COLOR_SHADER_CUTOUT_ROUNDED_CORNER, + VisualFactoryCache::COLOR_SHADER_CUTOUT_BORDERLINE, + VisualFactoryCache::COLOR_SHADER_CUTOUT_ROUNDED_BORDERLINE, + VisualFactoryCache::COLOR_SHADER_CUTOUT_BLUR_EDGE, + VisualFactoryCache::COLOR_SHADER_CUTOUT_ROUNDED_CORNER_BLUR_EDGE, }; // enum of required list when we select shader @@ -65,6 +80,7 @@ enum ColorVisualRequireFlag constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_ROUNDED_BLUR = 300; } // unnamed namespace + ColorVisualPtr ColorVisual::New(VisualFactoryCache& factoryCache, const Property::Map& properties) { ColorVisualPtr colorVisualPtr(new ColorVisual(factoryCache)); @@ -76,6 +92,7 @@ ColorVisualPtr ColorVisual::New(VisualFactoryCache& factoryCache, const Property ColorVisual::ColorVisual(VisualFactoryCache& factoryCache) : Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::COLOR), mBlurRadius(0.0f), + mCutoutPolicy(DevelColorVisual::CutoutPolicy::NONE), mAlwaysUsingBlurRadius(false) { } @@ -141,6 +158,22 @@ void ColorVisual::DoSetProperties(const Property::Map& propertyMap) } } } + + Property::Value* cutoutPolicyValue = propertyMap.Find(Toolkit::DevelColorVisual::Property::CUTOUT_POLICY, CUTOUT_POLICY_NAME); + if(cutoutPolicyValue) + { + int cutoutPolicy = static_cast(DevelColorVisual::CutoutPolicy::NONE) - 1; ///< Make always invalid + if(DALI_UNLIKELY(!Scripting::GetEnumerationProperty(*cutoutPolicyValue, CUTOUT_POLICY_TABLE, CUTOUT_POLICY_TABLE_COUNT, cutoutPolicy))) + { + std::ostringstream oss; + oss << *cutoutPolicyValue; + DALI_LOG_ERROR("ColorVisual:DoSetProperties:: CUTOUT_POLICY property has incorrect type : %d, value : %s\n", cutoutPolicyValue->GetType(), oss.str().c_str()); + } + else + { + mCutoutPolicy = static_cast(cutoutPolicy); + } + } } void ColorVisual::DoSetOnScene(Actor& actor) @@ -161,6 +194,7 @@ void ColorVisual::DoCreatePropertyMap(Property::Map& map) const map.Clear(); map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR); map.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, mImpl->mMixColor); + map.Insert(Toolkit::DevelColorVisual::Property::CUTOUT_POLICY, mCutoutPolicy); if(mImpl->mRenderer) { @@ -223,6 +257,12 @@ void ColorVisual::OnInitialize() mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON); } + if(IsCutoutRequired()) + { + int cutoutWithCornerRadius = (mCutoutPolicy == DevelColorVisual::CutoutPolicy::CUTOUT_VIEW_WITH_CORNER_RADIUS) ? 1 : 0; + mImpl->mRenderer.RegisterUniqueProperty("uCutoutWithCornerRadius", cutoutWithCornerRadius); + } + // Register transform properties mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } @@ -235,6 +275,7 @@ Shader ColorVisual::GenerateShader() const bool roundedCorner = IsRoundedCornerRequired(); bool borderline = IsBorderlineRequired(); bool blur = IsBlurRequired(); + bool cutout = IsCutoutRequired(); int shaderTypeFlag = ColorVisualRequireFlag::DEFAULT; if(blur) @@ -252,7 +293,7 @@ Shader ColorVisual::GenerateShader() const shaderTypeFlag |= ColorVisualRequireFlag::BORDERLINE; } - shaderType = SHADER_TYPE_TABLE[shaderTypeFlag]; + shaderType = cutout ? SHADER_TYPE_WITH_CUTOUT_TABLE[shaderTypeFlag] : SHADER_TYPE_TABLE[shaderTypeFlag]; shader = mFactoryCache.GetShader(shaderType); if(!shader) { @@ -279,6 +320,11 @@ Shader ColorVisual::GenerateShader() const vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n"; fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n"; } + if(cutout) + { + vertexShaderPrefixList += "#define IS_REQUIRED_CUTOUT\n"; + fragmentShaderPrefixList += "#define IS_REQUIRED_CUTOUT\n"; + } shader = mFactoryCache.GenerateAndSaveShader(shaderType, Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_COLOR_VISUAL_SHADER_VERT.data(), @@ -331,6 +377,11 @@ bool ColorVisual::IsBlurRequired() const return mAlwaysUsingBlurRadius || !EqualsZero(blurRadius); } +bool ColorVisual::IsCutoutRequired() const +{ + return (mCutoutPolicy != DevelColorVisual::CutoutPolicy::NONE); +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/color/color-visual.h b/dali-toolkit/internal/visuals/color/color-visual.h index 0a8a8b2..ae93885 100644 --- a/dali-toolkit/internal/visuals/color/color-visual.h +++ b/dali-toolkit/internal/visuals/color/color-visual.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_COLOR_VISUAL_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include // INTERNAL INCLUDES +#include #include namespace Dali @@ -131,6 +132,13 @@ protected: */ bool IsBlurRequired() const; + /** + * @brief Query whether the visual requires to cutout feature. + * + * @return Returns true if the cutout is required, false otherwise. + */ + bool IsCutoutRequired() const; + private: // Undefined ColorVisual(const ColorVisual& colorRenderer); @@ -139,8 +147,10 @@ private: ColorVisual& operator=(const ColorVisual& colorRenderer); private: - float mBlurRadius; ///< The blur radius - bool mAlwaysUsingBlurRadius : 1; ///< Whether we need the blur radius in shader always. + float mBlurRadius; ///< The blur radius + + DevelColorVisual::CutoutPolicy::Type mCutoutPolicy : 3; ///< The policy of cutout + bool mAlwaysUsingBlurRadius : 1; ///< Whether we need the blur radius in shader always. }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 3a61d4d..2e6f88c 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -62,6 +62,12 @@ public: COLOR_SHADER_ROUNDED_BORDERLINE, COLOR_SHADER_BLUR_EDGE, COLOR_SHADER_ROUNDED_CORNER_BLUR_EDGE, + COLOR_SHADER_CUTOUT, + COLOR_SHADER_CUTOUT_ROUNDED_CORNER, + COLOR_SHADER_CUTOUT_BORDERLINE, + COLOR_SHADER_CUTOUT_ROUNDED_BORDERLINE, + COLOR_SHADER_CUTOUT_BLUR_EDGE, + COLOR_SHADER_CUTOUT_ROUNDED_CORNER_BLUR_EDGE, BORDER_SHADER, BORDER_SHADER_ANTI_ALIASING, GRADIENT_SHADER_LINEAR_BOUNDING_BOX, diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index d4df78c..53a271b 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -53,6 +53,12 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN(VISUAL_SHADER_TYPE) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_ROUNDED_BORDERLINE) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_BLUR_EDGE) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_ROUNDED_CORNER_BLUR_EDGE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT_ROUNDED_CORNER) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT_BORDERLINE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT_ROUNDED_BORDERLINE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT_BLUR_EDGE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, COLOR_SHADER_CUTOUT_ROUNDED_CORNER_BLUR_EDGE) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, BORDER_SHADER) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, BORDER_SHADER_ANTI_ALIASING) DALI_ENUM_TO_STRING_WITH_SCOPE(Toolkit::Internal::VisualFactoryCache::ShaderType, GRADIENT_SHADER_LINEAR_BOUNDING_BOX) @@ -172,6 +178,7 @@ const char* const CORNER_RADIUS_POLICY("cornerRadiusPolicy"); // Color visual const char* const BLUR_RADIUS_NAME("blurRadius"); +const char* const CUTOUT_POLICY_NAME("cutoutPolicy"); // Image visual const char* const IMAGE_URL_NAME("url"); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index 1e7eea9..2a5a68d 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -74,6 +74,7 @@ extern const char* const CORNER_RADIUS_POLICY; // Color visual extern const char* const BLUR_RADIUS_NAME; +extern const char* const CUTOUT_POLICY_NAME; // Image visual extern const char* const IMAGE_URL_NAME; -- 2.7.4