Fix mis-using of RegisterProperty + Sync AnimatedImageVisual logic with ImageVisual 16/319816/7
authorEunki Hong <eunkiki.hong@samsung.com>
Sun, 3 Nov 2024 16:57:01 +0000 (01:57 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 11 Nov 2024 07:12:38 +0000 (16:12 +0900)
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 <eunkiki.hong@samsung.com>
12 files changed:
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual-shader-factory.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-factory-cache.cpp

index 3cd9f34bc905765b6eeb0ed02ec0c1bf08b9b7ce..bdb68dc53d2b4d7148198f80e0b4d959eec48f20 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visuals/animated-image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 
@@ -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<Impl::DummyControl&>(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<UniformData> 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<Impl::DummyControl&>(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<Vector4>("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<Vector4>("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<Vector4>("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<Vector4>("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<UniformData> 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<Impl::DummyControl&>(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<Vector4>("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<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  Property::Value* value = resultMap.Find(ImageVisual::Property::PIXEL_AREA);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(targetPixelArea, value->Get<Vector4>(), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Check uniform value updated
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector4>("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<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  value = resultMap.Find(ImageVisual::Property::PIXEL_AREA);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(targetPixelArea, value->Get<Vector4>(), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Check uniform value updated
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector4>("pixelArea", targetPixelArea), true, TEST_LOCATION);
+
+  END_TEST;
+}
index f4f6f0eb81f8171f28929b31a4cfa555f47cf723..2d30bbf792f990887ca7e8f397fa992feea5708e 100644 (file)
@@ -36,6 +36,7 @@
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
 
@@ -4510,3 +4511,85 @@ int UtcDaliImageVisualSynchronousSizing03(void)
 
   END_TEST;
 }
+
+int UtcDaliImageVisualUpdatePixelAreaByAction(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("ImageVisual animate pixel area");
+
+  static std::vector<UniformData> 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<Impl::DummyControl&>(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<Vector4>("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<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  Property::Value* value = resultMap.Find(ImageVisual::Property::PIXEL_AREA);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(targetPixelArea, value->Get<Vector4>(), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Check uniform value updated
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector4>("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<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+  value = resultMap.Find(ImageVisual::Property::PIXEL_AREA);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(targetPixelArea, value->Get<Vector4>(), TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+
+  // Check uniform value updated
+  DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue<Vector4>("pixelArea", targetPixelArea), true, TEST_LOCATION);
+
+  END_TEST;
+}
index 5fac9ca67333b6319e9c94a21601b244d0e7b0af..809f3b9222cdae700c864df96ff98edfa7fc8d39 100644 (file)
@@ -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;
index 8cd3d4feec899d820e03f285a9bc1baaaea3eee0..6e0aca8e94cd5545ef16809bc902b36cbbf32a90 100644 (file)
@@ -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<float>(mMaskingData->mCropToMask));
+    mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
   }
 
   // Enable PreMultipliedAlpha if it need.
index e65cd7a14215ae65b55b95e557a37668a947cee0..828bfdd79396af08960741f9351b701abc426cee 100644 (file)
@@ -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.
index 87de98ab3a557615f2df17666af9052575ca4b27..dd00e84cf6ab90a9ddcafdd4171c48a8838f89d4 100644 (file)
@@ -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
   {
index db8a20792eb4a19ab3542560877cb1613a8cb078..6917ac446efc848864f37bbfdb5705c5527a2963 100644 (file)
@@ -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())
   {
index 10337668ef245e645b6d5c31bb61e15854f22829..32efcd78d6608fb8bdab63d987712d471f59d6b8 100644 (file)
@@ -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<float>(mMaskingData->mCropToMask));
+    mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast<float>(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);
     }
index cfb348a2542093417dc20d13ef599638c431f607..b39056bca54068421ce482c945928789a17f3cdc 100644 (file)
@@ -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;
index b6b931a90dca9e6f039231ec74fbb0686268bff9..e3019057105d514256261b572876c8138c81eebe 100644 (file)
@@ -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;
 }
index 149873ed27a58dd6b1f5bf47de1d7d0883bcfd46..1fc041ec74bb3d8360d8dd1b37325288fe043c1b 100644 (file)
@@ -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)
index edf965c216d53156a0c8f96aa0798da0003442e5..3675d0a4ab563f216ff4cbf4b8659519258c546b 100644 (file)
@@ -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);