From: Eunki Hong Date: Sun, 3 Nov 2024 16:57:01 +0000 (+0900) Subject: Fix mis-using of RegisterProperty + Sync AnimatedImageVisual logic with ImageVisual X-Git-Tag: dali_2.3.50~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3b6fab3e7ad6d5d30ab275316affb9fa390c4ecc;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Fix mis-using of RegisterProperty + Sync AnimatedImageVisual logic with ImageVisual Their was several mis-ussing cases for RegisterProperty. Since the first value of RegisterProperty is the key of custom-property. But some codes works like "Set or Register". It will return invalid values when we try to get some item by INVALID_KEY. + Some codes are mis-implements at AnimatedImageVisual or AnimatedVectorVisual, SvgVisual. Let we follow them as latest code scenario, and add some UTC for it. Change-Id: I2a5b23a1cc321b2fc1fdd880ba85b8859451c153 Signed-off-by: Eunki Hong --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp index 3cd9f34bc9..bdb68dc53d 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -2001,6 +2002,58 @@ int UtcDaliAnimatedImageVisualPlayback(void) END_TEST; } +int UtcDaliAnimatedImageVisualCustomShader(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedImageVisualCustomShader Test custom shader"); + + VisualFactory factory = VisualFactory::Get(); + Property::Map properties; + Property::Map shader; + const std::string vertexShader = "Foobar"; + const std::string fragmentShader = "Foobar sampler2D Foobar"; + shader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader; + shader[Visual::Shader::Property::VERTEX_SHADER] = vertexShader; + + properties[Visual::Property::TYPE] = Visual::IMAGE; + properties[Visual::Property::SHADER] = shader; + properties[ImageVisual::Property::URL] = TEST_GIF_FILE_NAME; + + Visual::Base visual = factory.CreateVisual(properties); + + // trigger creation through setting on stage + DummyControl dummy = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(dummy.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + dummy.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + dummy.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + application.GetScene().Add(dummy); + + application.SendNotification(); + application.Render(); + + // Trigger count is 2 - load & render a frame + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + Renderer renderer = dummy.GetRendererAt(0); + Shader shader2 = renderer.GetShader(); + Property::Value value = shader2.GetProperty(Shader::Property::PROGRAM); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK(map); + + std::string resultFragmentShader, resultVertexShader; + Property::Value* fragment = map->Find("fragment"); // fragment key name from shader-impl.cpp + fragment->Get(resultFragmentShader); + DALI_TEST_CHECK(resultFragmentShader.find(fragmentShader) != std::string::npos); + + Property::Value* vertex = map->Find("vertex"); // vertex key name from shader-impl.cpp + vertex->Get(resultVertexShader); + DALI_TEST_CHECK(resultVertexShader.find(vertexShader) != std::string::npos); + + END_TEST; +} + int UtcDaliAnimatedImageVisualWrapMode(void) { ToolkitTestApplication application; @@ -2381,3 +2434,153 @@ int UtcDaliAnimatedImageVisualLoadNonRegularImage(void) END_TEST; } + +int UtcDaliAnimatedImageVisualAnimatePixelArea(void) +{ + ToolkitTestApplication application; + tet_infoline("AnimatedImageVisual animate pixel area"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME); + propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + 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, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + + Animation animation = Animation::New(4.0f); + animation.AnimateTo(DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, ImageVisual::Property::PIXEL_AREA), Vector4(0.0f, 0.0f, 0.0f, 1.0f)); + animation.AnimateTo(Property(actor, Actor::Property::COLOR), Color::WHITE); + animation.Play(); + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 0.5f, 1.0f)), true, TEST_LOCATION); + + application.Render(2000u); // End of animation + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 0.0f, 1.0f)), true, TEST_LOCATION); + + animation = Animation::New(4.0f); + animation.AnimateTo(DevelControl::GetVisualProperty(actor, DummyControl::Property::TEST_VISUAL, "pixelArea"), Vector4(1.0f, -1.0f, 2.0f, 2.0f)); + animation.Play(); + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.5f, -0.5f, 1.0f, 1.5f)), true, TEST_LOCATION); + + application.Render(2000u); // End of animation + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(1.0f, -1.0f, 2.0f, 2.0f)), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliAnimatedImageVisualUpdatePixelAreaByAction(void) +{ + ToolkitTestApplication application; + tet_infoline("AnimatedImageVisual update pixel area by action"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME); + propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + 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, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + + application.SendNotification(); + application.Render(0); + + // Default uniform is full-rect + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 1.0f, 1.0f)), true, TEST_LOCATION); + + Property::Map attributes; + Vector4 targetPixelArea = Vector4(0.0f, 1.0f, 1.0f, -1.0f); + + attributes.Add(ImageVisual::Property::PIXEL_AREA, targetPixelArea); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes); + + Property::Map resultMap; + resultMap = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + + Property::Value* value = resultMap.Find(ImageVisual::Property::PIXEL_AREA); + DALI_TEST_CHECK(value); + DALI_TEST_EQUALS(targetPixelArea, value->Get(), TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + + // Check uniform value updated + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", targetPixelArea), true, TEST_LOCATION); + + targetPixelArea = Vector4(-1.0f, -1.0f, 3.0f, 3.0f); + + attributes.Clear(); + attributes.Add(ImageVisual::Property::PIXEL_AREA, targetPixelArea); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes); + + resultMap = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + + value = resultMap.Find(ImageVisual::Property::PIXEL_AREA); + DALI_TEST_CHECK(value); + DALI_TEST_EQUALS(targetPixelArea, value->Get(), TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + + // Check uniform value updated + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", targetPixelArea), true, TEST_LOCATION); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index f4f6f0eb81..2d30bbf792 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -4510,3 +4511,85 @@ int UtcDaliImageVisualSynchronousSizing03(void) END_TEST; } + +int UtcDaliImageVisualUpdatePixelAreaByAction(void) +{ + ToolkitTestApplication application; + tet_infoline("ImageVisual animate pixel area"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + 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, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + + application.SendNotification(); + application.Render(0); + + // Default uniform is full-rect + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 1.0f, 1.0f)), true, TEST_LOCATION); + + Property::Map attributes; + Vector4 targetPixelArea = Vector4(0.0f, 1.0f, 1.0f, -1.0f); + + attributes.Add(ImageVisual::Property::PIXEL_AREA, targetPixelArea); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes); + + Property::Map resultMap; + resultMap = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + + Property::Value* value = resultMap.Find(ImageVisual::Property::PIXEL_AREA); + DALI_TEST_CHECK(value); + DALI_TEST_EQUALS(targetPixelArea, value->Get(), TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + + // Check uniform value updated + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", targetPixelArea), true, TEST_LOCATION); + + targetPixelArea = Vector4(-1.0f, -1.0f, 3.0f, 3.0f); + + attributes.Clear(); + attributes.Add(ImageVisual::Property::PIXEL_AREA, targetPixelArea); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes); + + resultMap = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + + value = resultMap.Find(ImageVisual::Property::PIXEL_AREA); + DALI_TEST_CHECK(value); + DALI_TEST_EQUALS(targetPixelArea, value->Get(), TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + + // Check uniform value updated + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", targetPixelArea), true, TEST_LOCATION); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp index 5fac9ca673..809f3b9222 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp @@ -1384,6 +1384,16 @@ int UtcDaliNPatchVisualAuxiliaryImage01(void) Renderer renderer = dummy.GetRendererAt(0); auto textures = renderer.GetTextures(); DALI_TEST_EQUALS(textures.GetTextureCount(), 2, TEST_LOCATION); + + // SceneOff + SceneOn immediatly. Let we check cached texture still exist. + dummy.Unparent(); + application.GetScene().Add(dummy); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 0), false, TEST_LOCATION); + UnparentAndReset(dummy); END_TEST; diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index 8cd3d4feec..6e0aca8e94 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -113,6 +113,8 @@ static constexpr auto FIRST_LOOP = 0u; constexpr float MINIMUM_FRAME_SPEED_FACTOR(0.01f); constexpr float MAXIMUM_FRAME_SPEED_FACTOR(100.0f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); + constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; #if defined(DEBUG_ENABLED) @@ -462,12 +464,15 @@ void AnimatedImageVisual::EnablePreMultipliedAlpha(bool preMultiplied) { if(mImpl->mRenderer) { - if(mPreMultipliedAlphaIndex != Property::INVALID_INDEX || !preMultiplied) + if(mPreMultipliedAlphaIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mPreMultipliedAlphaIndex, preMultiplied ? 1.0f : 0.0f); + } + else if(!preMultiplied) { - // RegisterUniqueProperty call SetProperty internally. // Register PREMULTIPLIED_ALPHA only if it become false. // Default PREMULTIPLIED_ALPHA value is 1.0f, at image-visual-shader-factory.cpp - mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterUniqueProperty(mPreMultipliedAlphaIndex, PREMULTIPLIED_ALPHA, preMultiplied ? 1.0f : 0.0f); + mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::Visual::Property::PREMULTIPLIED_ALPHA, PREMULTIPLIED_ALPHA, preMultiplied ? 1.0f : 0.0f); } } @@ -645,6 +650,20 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, case Toolkit::ImageVisual::Property::PIXEL_AREA: { value.Get(mPixelArea); + + if(DALI_UNLIKELY(mImpl->mRenderer)) + { + // Unusual case. SetProperty called after OnInitialize(). + // Assume that DoAction call UPDATE_PROPERTY. + if(mPixelAreaIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mPixelAreaIndex, mPixelArea); + } + else if(mPixelArea != FULL_TEXTURE_RECT) + { + mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + } + } break; } case Toolkit::ImageVisual::Property::WRAP_MODE_U: @@ -938,19 +957,54 @@ void AnimatedImageVisual::UpdateShader() Shader AnimatedImageVisual::GenerateShader() const { - bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; - bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; Shader shader; - shader = mImageVisualShaderFactory.GetShader( - mFactoryCache, - ImageVisualShaderFeature::FeatureBuilder() - .ApplyDefaultTextureWrapMode(defaultWrapMode) - .EnableRoundedCorner(IsRoundedCornerRequired(), IsSquircleCornerRequired()) - .EnableBorderline(IsBorderlineRequired()) - .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)); + if(mImpl->mCustomShader) + { + shader = Shader::New(mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource().data() : mImpl->mCustomShader->mVertexShader, + mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource().data() : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mHints); + + shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + + // Most of image visual shader user (like svg, animated vector image visual) use pre-multiplied alpha. + // If the visual dont want to using pre-multiplied alpha, it should be set as 0.0f as renderer side. + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); + } + else + { + bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; + + shader = mImageVisualShaderFactory.GetShader( + mFactoryCache, + ImageVisualShaderFeature::FeatureBuilder() + .ApplyDefaultTextureWrapMode(defaultWrapMode) + .EnableRoundedCorner(IsRoundedCornerRequired(), IsSquircleCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) + .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)); + } return shader; } +Dali::Property AnimatedImageVisual::OnGetPropertyObject(Dali::Property::Key key) +{ + if((key.type == Property::Key::INDEX && key.indexKey == Toolkit::ImageVisual::Property::PIXEL_AREA) || + (key.type == Property::Key::STRING && key.stringKey == PIXEL_AREA_UNIFORM_NAME)) + { + if(DALI_LIKELY(mImpl->mRenderer)) + { + if(mPixelAreaIndex == Property::INVALID_INDEX) + { + mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + } + return Dali::Property(mImpl->mRenderer, mPixelAreaIndex); + } + } + + Handle handle; + return Dali::Property(handle, Property::INVALID_INDEX); +} + void AnimatedImageVisual::OnInitialize() { CreateImageCache(); @@ -970,17 +1024,17 @@ void AnimatedImageVisual::OnInitialize() { Vector2 wrapMode(mWrapModeU - WrapMode::CLAMP_TO_EDGE, mWrapModeV - WrapMode::CLAMP_TO_EDGE); wrapMode.Clamp(Vector2::ZERO, Vector2(2.f, 2.f)); - mImpl->mRenderer.RegisterProperty(WRAP_MODE_UNIFORM_NAME, wrapMode); + mImpl->mRenderer.RegisterUniqueProperty(WRAP_MODE_UNIFORM_NAME, wrapMode); } if(mPixelArea != FULL_TEXTURE_RECT) { - mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + mPixelAreaIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); } if(mMaskingData) { - mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); + mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); } // Enable PreMultipliedAlpha if it need. 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 e65cd7a142..828bfdd793 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -200,6 +200,11 @@ protected: */ Shader GenerateShader() const override; + /** + * @copydoc Visual::Base::OnGetPropertyObject + */ + Dali::Property OnGetPropertyObject(Dali::Property::Key key) override; + private: /** * @brief Initialize the animated image variables. diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 87de98ab3a..dd00e84cf6 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -48,10 +48,12 @@ namespace Internal { namespace { -const int CUSTOM_PROPERTY_COUNT(1); // pixel area, +const int CUSTOM_PROPERTY_COUNT(1); // PixelArea const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); + // stop behavior DALI_ENUM_TO_STRING_TABLE_BEGIN(STOP_BEHAVIOR) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME) @@ -899,6 +901,10 @@ Shader AnimatedVectorImageVisual::GenerateShader() const mImpl->mCustomShader->mHints); shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + + // Most of image visual shader user (like svg, animated vector image visual) use pre-multiplied alpha. + // If the visual dont want to using pre-multiplied alpha, it should be set as 0.0f as renderer side. + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); } else { diff --git a/dali-toolkit/internal/visuals/image/image-visual-shader-factory.cpp b/dali-toolkit/internal/visuals/image/image-visual-shader-factory.cpp index db8a20792e..6917ac446e 100644 --- a/dali-toolkit/internal/visuals/image/image-visual-shader-factory.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual-shader-factory.cpp @@ -36,7 +36,7 @@ namespace { const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); -constexpr float ALPHA_PRE_MULTIPLIED(1.0f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); constexpr int CUSTOM_PROPERTY_COUNT(2); // PixelArea, pre-multiplied alpha @@ -154,7 +154,7 @@ Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, con // Most of image visual shader user (like svg, animated vector image visual) use pre-multiplied alpha. // If the visual dont want to using pre-multiplied alpha, it should be set as 0.0f as renderer side. - shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_PRE_MULTIPLIED); + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); if(featureBuilder.IsEnabledAlphaMaskingOnRendering()) { diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 10337668ef..32efcd78d6 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -104,6 +104,8 @@ DALI_ENUM_TO_STRING_TABLE_END(RELEASE_POLICY) const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); + constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_UNIFIED_YUV_AND_RGB = 300; @@ -354,7 +356,14 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va { // Unusual case. SetProperty called after OnInitialize(). // Assume that DoAction call UPDATE_PROPERTY. - mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + if(mPixelAreaIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mPixelAreaIndex, mPixelArea); + } + else if(mPixelArea != FULL_TEXTURE_RECT) + { + mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + } } break; } @@ -623,6 +632,11 @@ void ImageVisual::OnInitialize() mImpl->mRenderer = DecoratedVisualRenderer::New(geometry, shader); mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); + if(mPixelArea != FULL_TEXTURE_RECT) + { + mPixelAreaIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + } + //Register transform properties mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); @@ -630,7 +644,7 @@ void ImageVisual::OnInitialize() if(mMaskingData) { - mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); + mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); } } @@ -887,11 +901,6 @@ void ImageVisual::DoSetOnScene(Actor& actor) mPlacementActor = actor; - if(mPixelArea != FULL_TEXTURE_RECT) - { - mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea); - } - if(mLoadState == TextureManager::LoadState::LOAD_FINISHED) { actor.AddRenderer(mImpl->mRenderer); @@ -999,12 +1008,15 @@ void ImageVisual::EnablePreMultipliedAlpha(bool preMultiplied) { if(mImpl->mRenderer) { - if(mPreMultipliedAlphaIndex != Property::INVALID_INDEX || !preMultiplied) + if(mPreMultipliedAlphaIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mPreMultipliedAlphaIndex, preMultiplied ? 1.0f : 0.0f); + } + else if(!preMultiplied) { - // RegisterUniqueProperty call SetProperty internally. // Register PREMULTIPLIED_ALPHA only if it become false. // Default PREMULTIPLIED_ALPHA value is 1.0f, at image-visual-shader-factory.cpp - mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterUniqueProperty(mPreMultipliedAlphaIndex, PREMULTIPLIED_ALPHA, preMultiplied ? 1.0f : 0.0f); + mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::Visual::Property::PREMULTIPLIED_ALPHA, PREMULTIPLIED_ALPHA, preMultiplied ? 1.0f : 0.0f); } } @@ -1399,6 +1411,10 @@ Shader ImageVisual::GenerateShader() const { shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); } + + // Most of image visual shader user (like svg, animated vector image visual) use pre-multiplied alpha. + // If the visual dont want to using pre-multiplied alpha, it should be set as 0.0f as renderer side. + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); } return shader; @@ -1406,13 +1422,14 @@ Shader ImageVisual::GenerateShader() const Dali::Property ImageVisual::OnGetPropertyObject(Dali::Property::Key key) { - if((key.type == Property::Key::INDEX && key.indexKey == Toolkit::ImageVisual::Property::PIXEL_AREA) || (key.type == Property::Key::STRING && key.stringKey == PIXEL_AREA_UNIFORM_NAME)) + if((key.type == Property::Key::INDEX && key.indexKey == Toolkit::ImageVisual::Property::PIXEL_AREA) || + (key.type == Property::Key::STRING && key.stringKey == PIXEL_AREA_UNIFORM_NAME)) { if(DALI_LIKELY(mImpl->mRenderer)) { if(mPixelAreaIndex == Property::INVALID_INDEX) { - mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea); + mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea); } return Dali::Property(mImpl->mRenderer, mPixelAreaIndex); } diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index cfb348a254..b39056bca5 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -94,8 +94,15 @@ void NPatchVisual::LoadImages() ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; - // Register PREMULTIPLIED_ALPHA property here. - mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterUniqueProperty(mPreMultipliedAlphaIndex, PREMULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled() ? 1.0f : 0.0f); + if(mPreMultipliedAlphaIndex != Property::INVALID_INDEX) + { + mImpl->mRenderer.SetProperty(mPreMultipliedAlphaIndex, IsPreMultipliedAlphaEnabled() ? 1.0f : 0.0f); + } + else + { + // Register PREMULTIPLIED_ALPHA here. + mPreMultipliedAlphaIndex = mImpl->mRenderer.RegisterProperty(Toolkit::Visual::Property::PREMULTIPLIED_ALPHA, PREMULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled() ? 1.0f : 0.0f); + } TextureManager::MaskingDataPointer maskingDataPtr = nullptr; ImageAtlasManagerPtr imageAtlasManagerPtr = nullptr; diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index b6b931a90d..e301905710 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -45,6 +45,8 @@ const int CUSTOM_PROPERTY_COUNT(1); // atlas constexpr Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); + } // namespace SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties) @@ -423,7 +425,7 @@ void SvgVisual::RasterizeComplete(int32_t rasterizeId, Dali::TextureSet textureS if(DALI_UNLIKELY(mAtlasRect != FULL_TEXTURE_RECT)) { // Register atlas rect property only if it's not full texture rect. - mAtlasRectIndex = mImpl->mRenderer.RegisterUniqueProperty(mAtlasRectIndex, ATLAS_RECT_UNIFORM_NAME, mAtlasRect); + mAtlasRectIndex = mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, mAtlasRect); } } else @@ -546,6 +548,10 @@ Shader SvgVisual::GenerateShader() const mImpl->mCustomShader->mHints); shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + + // Most of image visual shader user (like svg, animated vector image visual) use pre-multiplied alpha. + // If the visual dont want to using pre-multiplied alpha, it should be set as 0.0f as renderer side. + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); } return shader; } diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 149873ed27..1fc041ec74 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -1132,6 +1132,13 @@ Property::Index Visual::Base::GetPropertyIndex(Property::Key key) } } + // Fast-out for invalid key. + if((key.type == Property::Key::INDEX && key.indexKey == Property::INVALID_KEY) || + (key.type == Property::Key::STRING && key.stringKey.empty())) + { + return Property::INVALID_INDEX; + } + Property::Index index = mImpl->mRenderer.GetPropertyIndex(key); if(index == Property::INVALID_INDEX) diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.cpp b/dali-toolkit/internal/visuals/visual-factory-cache.cpp index edf965c216..3675d0a4ab 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-cache.cpp @@ -45,6 +45,8 @@ namespace { const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +constexpr float ALPHA_VALUE_PREMULTIPLIED(1.0f); + constexpr auto LOAD_IMAGE_YUV_PLANES_ENV = "DALI_LOAD_IMAGE_YUV_PLANES"; bool NeedToLoadYuvPlanes() @@ -456,6 +458,7 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec { shader = GenerateAndSaveShader(IMAGE_SHADER, Dali::Shader::GetVertexShaderPrefix() + SHADER_IMAGE_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_IMAGE_VISUAL_SHADER_FRAG.data()); shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + shader.RegisterProperty(PREMULTIPLIED_ALPHA, ALPHA_VALUE_PREMULTIPLIED); } renderer.SetGeometry(geometry); renderer.SetShader(shader);