[Tizen] Reset To 2.3.42 40/318940/1
authorSeungho Baek <sbsh.baek@samsung.com>
Fri, 11 Oct 2024 02:52:54 +0000 (11:52 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Fri, 11 Oct 2024 02:52:54 +0000 (11:52 +0900)
Change-Id: I43189c21c63612bca175381c77a99bae236da1fc
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-PropertyValue.cpp
dali/graphics-api/graphics-types.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp
dali/public-api/dali-core-version.cpp
dali/public-api/object/property-value.cpp
dali/public-api/object/property-value.h
packaging/dali.spec

index 79855870fe319dc7fd39acb3603f2d36249935d3..cfbac54e9b549312f2260d006e07d10af6eb996c 100644 (file)
 #include <mesh-builder.h>
 #include <stdlib.h>
 
+#include <dali/public-api/common/vector-wrapper.h>
+
 #include <algorithm>
 #include <iostream>
+#include <utility>
 
 using std::max;
 using namespace Dali;
@@ -14564,14 +14567,14 @@ int UtcDaliAnimationAnimateByInvalidParameters(void)
       // not mathing properties (VECTOR3, FLOAT)
       animation.AnimateBy(Property(actor, Actor::Property::POSITION), Property::Value(10.f));
     },
-    "Property and target types don't match");
+    "Target types could not be convert to Property type");
 
   DALI_TEST_ASSERTION(
     {
       // not mathing properties (VECTOR3.A, VECTOR2)
       animation.AnimateBy(Property(actor, Actor::Property::COLOR_ALPHA), Property::Value(Property::VECTOR2));
     },
-    "Property and target types don't match");
+    "Target types could not be convert to Property type");
 
   DALI_TEST_ASSERTION(
     {
@@ -14623,19 +14626,12 @@ int UtcDaliAnimationAnimateToInvalidParameters(void)
     },
     "Target value is not animatable");
 
-  DALI_TEST_ASSERTION(
-    {
-      // not mathing properties (FLOAT, INT)
-      animation.AnimateTo(Property(actor, Actor::Property::SCALE_Y), Property::Value(10));
-    },
-    "Property and target types don't match");
-
   DALI_TEST_ASSERTION(
     {
       // not mathing properties (VECTOR3, VECTOR2)
       animation.AnimateTo(Property(actor, Actor::Property::COLOR), Property::Value(Property::VECTOR2));
     },
-    "Property and target types don't match");
+    "Target types could not be convert to Property type");
 
   DALI_TEST_ASSERTION(
     {
@@ -14702,7 +14698,7 @@ int UtcDaliAnimationAnimateBetweenInvalidParameters(void)
       keyframes.Add(0.5f, Property::Value(Vector4(1, 2, 3, 4)));
       animation.AnimateBetween(Property(actor, Actor::Property::MAXIMUM_SIZE), keyframes);
     },
-    "Property and target types don't match");
+    "Target types could not be convert to Property type");
 
   DALI_TEST_ASSERTION(
     {
@@ -14716,6 +14712,130 @@ int UtcDaliAnimationAnimateBetweenInvalidParameters(void)
   END_TEST;
 }
 
+int UtcDaliAnimationAnimateConvertPropertyValueParameters(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  application.GetScene().Add(actor);
+
+  // Create the animation
+  Animation animation = Animation::New(1.0f);
+
+  Property::Index indexBoolean = actor.RegisterProperty("animationBoolean", Property::Value(false), Property::ANIMATABLE);
+  Property::Index indexFloat   = actor.RegisterProperty("animationFloat", Property::Value(0.0f), Property::ANIMATABLE);
+  Property::Index indexInteger = actor.RegisterProperty("animationInteger", Property::Value(0), Property::ANIMATABLE);
+
+  // clang-format off
+  const std::vector<std::pair<Property::Index, Property::Value>> indexValueList =
+  {
+    {indexBoolean, actor.GetProperty(indexBoolean)},
+    {indexFloat, actor.GetProperty(indexFloat)},
+    {indexInteger, actor.GetProperty(indexInteger)},
+  };
+
+  // Piar of relative value - {except value as relative value per each type of properties}
+  const std::vector<std::pair<Property::Value, std::vector<Property::Value>>> testExceptValueList =
+  {
+    {
+      Property::Value(true),
+      {
+        Property::Value(true), Property::Value(1.0f), Property::Value(1),
+      }
+    },
+    {
+      Property::Value(2.0f),
+      {
+        Property::Value(true), Property::Value(2.0f), Property::Value(2),
+      }
+    },
+    {
+      Property::Value(3),
+      {
+        Property::Value(true), Property::Value(3.0f), Property::Value(3),
+      }
+    },
+  };
+  // clang-format on
+
+  // Let we test both AnimateBy and AnimateTo and AnimateBetween as one UTC.
+  for(auto animateType = 0; animateType < 3; ++animateType)
+  {
+    tet_printf("Animation type test : %s\n", std::vector<std::string>({"AnimateBy", "AnimateTo", "AnimateBetween"})[animateType].c_str());
+    for(const auto& valueExceptPair : testExceptValueList)
+    {
+      {
+        std::ostringstream oss;
+        oss << valueExceptPair.first;
+        tet_printf("Animate required value : %s\n", oss.str().c_str());
+      }
+      for(const auto& indexValuePair : indexValueList)
+      {
+        if(animateType == 0u)
+        {
+          animation.AnimateBy(Property(actor, indexValuePair.first), valueExceptPair.first);
+        }
+        else if(animateType == 1u)
+        {
+          animation.AnimateTo(Property(actor, indexValuePair.first), valueExceptPair.first);
+        }
+        else if(animateType == 2u)
+        {
+          Dali::KeyFrames keyFrames = Dali::KeyFrames::New();
+
+          // Convert original value type as excepted type.
+          auto originalValue = indexValuePair.second;
+          originalValue.ConvertType(valueExceptPair.first.GetType());
+
+          keyFrames.Add(0.0f, originalValue);
+          keyFrames.Add(1.0f, valueExceptPair.first);
+          animation.AnimateBetween(Property(actor, indexValuePair.first), keyFrames);
+        }
+      }
+      animation.Play();
+
+      const auto& exceptValueList = valueExceptPair.second;
+
+      // Test except value list size is same as index value list size. (All property should have except value)
+      DALI_TEST_EQUALS(exceptValueList.size(), indexValueList.size(), TEST_LOCATION);
+
+      // Check cached event thread values are expect.
+      for(auto i = 0u; i < indexValueList.size(); ++i)
+      {
+        DALI_TEST_EQUALS(actor.GetProperty(indexValueList[i].first), exceptValueList[i], TEST_LOCATION);
+      }
+
+      // Check current vaules are not animated yet.
+      for(auto i = 0u; i < indexValueList.size(); ++i)
+      {
+        DALI_TEST_EQUALS(actor.GetCurrentProperty(indexValueList[i].first), indexValueList[i].second, TEST_LOCATION);
+      }
+
+      application.SendNotification();
+      application.Render(500);
+      application.SendNotification();
+      application.Render(500 + 10); ///< Note, we don't allow 1 frame animation finished. To fair test, render 2 frames.
+
+      // Check current vaules are except.
+      for(auto i = 0u; i < indexValueList.size(); ++i)
+      {
+        DALI_TEST_EQUALS(actor.GetCurrentProperty(indexValueList[i].first), exceptValueList[i], TEST_LOCATION);
+      }
+
+      animation.Clear();
+      // Reset to base value, for fair test.
+      for(const auto& indexValuePair : indexValueList)
+      {
+        actor.SetProperty(indexValuePair.first, indexValuePair.second);
+      }
+      application.SendNotification();
+      application.Render();
+    }
+  }
+
+  END_TEST;
+}
+
 namespace // Purposefully left this in the middle as the values in this namespace are only used for the subsequent two test cases
 {
 enum TestFunction
index 449fce25045a901046ecb225e30aabbac1ecae28..75401d6b73d2ed6be712027c4cd3caeee01b0bf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 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.
 #include <dali/public-api/dali-core.h>
 #include <stdlib.h>
 
+#include <dali/public-api/common/vector-wrapper.h>
+
+#include <algorithm>
 #include <iomanip>
 #include <iostream>
+#include <utility>
 
 using namespace Dali;
 
@@ -238,7 +242,7 @@ int UtcDaliPropertyValueConstructorsRectP(void)
   Property::Value value(v);
 
   DALI_TEST_EQUALS(value.GetType(), Property::RECTANGLE, TEST_LOCATION);
-  DALI_TEST_CHECK(value.Get<Rect<int> >() == v);
+  DALI_TEST_CHECK(value.Get<Rect<int>>() == v);
 
   END_TEST;
 }
@@ -248,7 +252,7 @@ int UtcDaliPropertyValueConstructorsRectTypeP(void)
   Property::Value value(Property::RECTANGLE);
 
   DALI_TEST_CHECK(value.GetType() == Property::RECTANGLE);
-  DALI_TEST_CHECK(value.Get<Rect<int> >() == Rect<int>(0, 0, 0, 0));
+  DALI_TEST_CHECK(value.Get<Rect<int>>() == Rect<int>(0, 0, 0, 0));
 
   END_TEST;
 }
@@ -456,7 +460,7 @@ int UtcDaliPropertyValueCopyConstructorMatrixP(void)
 
 int UtcDaliPropertyValueCopyConstructorRectP(void)
 {
-  CheckCopyCtorP<Rect<int> > check(Rect<int>(1.0, 1.0, 1.0, 1.0));
+  CheckCopyCtorP<Rect<int>> check(Rect<int>(1.0, 1.0, 1.0, 1.0));
   END_TEST;
 }
 
@@ -813,7 +817,7 @@ int UtcDaliPropertyValueMoveAssignmentOperator(void)
   DALI_TEST_EQUALS(valueFloat, 1.0f, TEST_LOCATION);
 
   // Self std::move assignment make compile warning over gcc-13. Let we ignore the warning.
-#if (__GNUC__ >= 13)
+#if(__GNUC__ >= 13)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wself-move"
 #endif
@@ -821,7 +825,7 @@ int UtcDaliPropertyValueMoveAssignmentOperator(void)
   value2 = std::move(value2);
   DALI_TEST_EQUALS(true, value2.Get(valueFloat), TEST_LOCATION);
   DALI_TEST_EQUALS(valueFloat, 1.0f, TEST_LOCATION);
-#if (__GNUC__ >= 13)
+#if(__GNUC__ >= 13)
 #pragma GCC diagnostic pop
 #endif
 
@@ -918,7 +922,7 @@ int UtcDaliPropertyValueGetRectP(void)
 {
   Property::Value value(Rect<int>(1, 2, 3, 4));
   Rect<int>       result(4, 3, 2, 1);
-  DALI_TEST_EQUALS(Rect<int>(1, 2, 3, 4), value.Get<Rect<int> >(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Rect<int>(1, 2, 3, 4), value.Get<Rect<int>>(), TEST_LOCATION);
   DALI_TEST_EQUALS(true, value.Get(result), TEST_LOCATION);
   DALI_TEST_EQUALS(Rect<int>(1, 2, 3, 4), result, TEST_LOCATION);
   END_TEST;
@@ -928,7 +932,7 @@ int UtcDaliPropertyValueGetRectN(void)
 {
   Property::Value value;
   Rect<int>       result(4, 3, 2, 1);
-  DALI_TEST_EQUALS(Rect<int>(0, 0, 0, 0), value.Get<Rect<int> >(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Rect<int>(0, 0, 0, 0), value.Get<Rect<int>>(), TEST_LOCATION);
   DALI_TEST_EQUALS(false, value.Get(result), TEST_LOCATION);
   DALI_TEST_EQUALS(Rect<int>(4, 3, 2, 1), result, TEST_LOCATION);
   Property::Value value2("");
@@ -1483,6 +1487,122 @@ int UtcDaliPropertyValueEqualMapType(void)
   END_TEST;
 }
 
+int UtcDaliPropertyValueConvertScalarType(void)
+{
+  tet_infoline("Check Property::Value type conversion.");
+
+  // Piar of input value - {except value as relative value per each type of properties}
+  // clang-format off
+  const std::vector<Property::Type> testConvertTypeList =
+  {
+    Property::BOOLEAN, Property::FLOAT, Property::INTEGER,
+  };
+  const std::vector<std::pair<Property::Value, std::vector<Property::Value>>> testExceptValueList =
+  {
+    {
+      Property::Value(true),
+      {
+        Property::Value(true), Property::Value(1.0f), Property::Value(1),
+      }
+    },
+    {
+      Property::Value(2.0f),
+      {
+        Property::Value(true), Property::Value(2.0f), Property::Value(2),
+      }
+    },
+    {
+      Property::Value(3),
+      {
+        Property::Value(true), Property::Value(3.0f), Property::Value(3),
+      }
+    },
+  };
+  // clang-format on
+
+  for(auto& valueExceptPair : testExceptValueList)
+  {
+    const auto& exceptValueList = valueExceptPair.second;
+
+    // Test except value list size is same as conversion type list size. (All property should have except value)
+    DALI_TEST_EQUALS(exceptValueList.size(), testConvertTypeList.size(), TEST_LOCATION);
+
+    // Check cached event thread values are expect.
+    for(auto i = 0u; i < testConvertTypeList.size(); ++i)
+    {
+      // Check expect type is valid.
+      const Property::Type convertType = testConvertTypeList[i];
+      DALI_TEST_EQUALS(convertType, exceptValueList[i].GetType(), TEST_LOCATION);
+
+      Property::Value convertedValue = valueExceptPair.first;
+
+      tet_printf("Test convert from %d to %d\n", static_cast<int>(convertedValue.GetType()), static_cast<int>(convertType));
+
+      DALI_TEST_CHECK(convertedValue.ConvertType(convertType));
+      DALI_TEST_EQUALS(convertedValue, exceptValueList[i], TEST_LOCATION);
+    }
+  }
+  END_TEST;
+}
+
+int UtcDaliPropertyValueConvertFailed(void)
+{
+  tet_infoline("Check Property::Value type conversion failed.");
+
+  float           a[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f};
+  Property::Array array;
+  Property::Map   map;
+
+  // clang-format off
+  const std::vector<Property::Value> scalarValueList =
+  {
+    Property::Value(false), Property::Value(1.0f), Property::Value(2)
+  };
+  const std::vector<Property::Value> conversionInvalidValueList =
+  {
+    Property::Value(),
+    Property::Value(Vector2()), Property::Value(Vector3()), Property::Value(Vector4()),
+
+    Property::Value(Matrix(a)),
+    Property::Value(Matrix3(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f)),
+
+    Property::Value(Rect<int32_t>(2, 3, 4, 5)),
+    Property::Value(AngleAxis(Radian(20.0f), Vector3(0.0f, 1.0f, 0.0f))),
+    Property::Value(std::string("Hell, o, World!")),
+    Property::Value(Extents(4, 8, 5, 2)),
+
+    Property::Value(array),
+    Property::Value(map),
+  };
+  // clang-format on
+
+  for(int i = Property::Type::NONE; i <= Property::Type::EXTENTS; ++i)
+  {
+    Property::Type type(static_cast<Property::Type>(i));
+
+    // Test convert for scalar value type
+    for(auto& value : scalarValueList)
+    {
+      // Copy value
+      Property::Value convertedValue      = value;
+      bool            expectConvertResult = (type == Property::BOOLEAN || type == Property::FLOAT || type == Property::INTEGER);
+
+      DALI_TEST_EQUALS(convertedValue.ConvertType(type), expectConvertResult, TEST_LOCATION);
+    }
+
+    // Test convert invalid for conversion invalid types
+    for(auto& value : conversionInvalidValueList)
+    {
+      // Copy value
+      Property::Value convertedValue      = value;
+      bool            expectConvertResult = (type == convertedValue.GetType());
+
+      DALI_TEST_EQUALS(convertedValue.ConvertType(type), expectConvertResult, TEST_LOCATION);
+    }
+  }
+  END_TEST;
+}
+
 int UtcDaliPropertyValueOutputStream(void)
 {
   TestApplication application;
index 4fd4adcb6e77f1e1b170abcdc57500ff5da028a9..77800058bbd632acd52e179756e67b200815519d 100644 (file)
@@ -37,6 +37,9 @@ class Framebuffer;
 class Program;
 class Shader;
 class Texture;
+class RenderTarget;
+class RenderPass;
+class Sampler;
 
 /**
  * @brief Structure describes 2D offset
@@ -575,7 +578,7 @@ struct RasterizationState
 struct InputAssemblyState
 {
   PrimitiveTopology topology{};
-  bool              primitiveRestartEnable{true};
+  bool              primitiveRestartEnable{false};
 
   auto& SetTopology(PrimitiveTopology value)
   {
@@ -585,7 +588,7 @@ struct InputAssemblyState
 
   auto& SetPrimitiveRestartEnable(bool value)
   {
-    primitiveRestartEnable = true;
+    primitiveRestartEnable = value;
     return *this;
   }
 };
@@ -1293,10 +1296,59 @@ inline CommandBufferUsageFlags operator|(T flags, CommandBufferUsageFlagBits bit
   return static_cast<CommandBufferUsageFlags>(flags) | static_cast<CommandBufferUsageFlags>(bit);
 }
 
+enum class ResourceType
+{
+  PROGRAM,
+  BUFFER,
+  SAMPLER,
+  TEXTURE
+};
+
+struct ProgramResourceBindingInfo
+{
+  Graphics::Program* program;
+  uint32_t           count;
+};
+
+struct BufferResourceBindingInfo;
+struct TextureResourceBindingInfo;
+struct SamplerResourceBindingInfo;
+
+struct CommandBufferResourceBinding
+{
+  ResourceType type; ///< Type of resource
+
+  union
+  {
+    ProgramResourceBindingInfo* programBinding{nullptr};
+    BufferResourceBindingInfo*  bufferBinding;
+    TextureResourceBindingInfo* textureBinding;
+    SamplerResourceBindingInfo* samplerBinding;
+  };
+};
+
 struct CommandBufferBeginInfo
 {
   CommandBufferUsageFlags usage;
-  // Don't care about inheritance yet. Can extend as required.
+
+  std::vector<CommandBufferResourceBinding>* resourceBindings{nullptr}; ///< Sets resource binding hints
+  const RenderPass*                          renderPass{nullptr};
+  const RenderTarget*                        renderTarget{nullptr};
+  auto&                                      SetUsage(CommandBufferUsageFlags flags)
+  {
+    usage = flags;
+    return *this;
+  }
+  auto& SetRenderPass(const RenderPass& value)
+  {
+    renderPass = &value;
+    return *this;
+  }
+  auto& SetRenderTarget(const RenderTarget& value)
+  {
+    renderTarget = &value;
+    return *this;
+  }
 };
 
 /**
@@ -1517,8 +1569,7 @@ struct DefaultDeleter
   template<class P, template<typename> typename U>
   DefaultDeleter(const U<P>& deleter)
   {
-    deleteFunction = [](T* object)
-    { U<P>()(static_cast<P*>(object)); };
+    deleteFunction = [](T* object) { U<P>()(static_cast<P*>(object)); };
   }
 
   /**
index 908126e562a211767d694263e45f60a89b37274b..831a61d945b5467a52ddb3f5bacb4e96b7c29af8 100644 (file)
@@ -118,19 +118,20 @@ inline bool IsAnimatable(Property::Type type)
 }
 
 /**
- * Helper to validate animation input values
+ * Helper to validate and convert animation input values
  *
- * @param propertyType type of the property that is being animated
- * @param destinationType type of the target
- * @param period time period of the animation
+ * @param[in] propertyType type of the property that is being animated
+ * @param[in] period time period of the animation
+ * @param[in, out] convertedValue if the value needs conversion, this will contain the converted value.
  */
-void ValidateParameters(Property::Type propertyType, Property::Type destinationType, const TimePeriod& period)
+void ValidateAndConvertParameters(Property::Type propertyType, const TimePeriod& period, Property::Value& convertedValue)
 {
   // destination value has to be animatable
   DALI_ASSERT_ALWAYS(IsAnimatable(propertyType) && "Property type is not animatable");
-  DALI_ASSERT_ALWAYS(IsAnimatable(destinationType) && "Target value is not animatable");
-  DALI_ASSERT_ALWAYS(propertyType == destinationType && "Property and target types don't match");
+  DALI_ASSERT_ALWAYS(IsAnimatable(convertedValue.GetType()) && "Target value is not animatable");
   DALI_ASSERT_ALWAYS(period.durationSeconds >= 0 && "Duration must be >=0");
+
+  DALI_ASSERT_ALWAYS(convertedValue.ConvertType(propertyType) && "Target types could not be convert to Property type");
 }
 
 /**
@@ -566,22 +567,18 @@ void Animation::AnimateBy(Property& target, Property::Value relativeValue, TimeP
 
 void Animation::AnimateBy(Property& target, Property::Value relativeValue, AlphaFunction alpha, TimePeriod period)
 {
-  Object&              object          = GetImplementation(target.object);
-  const Property::Type propertyType    = object.GetPropertyType(target.propertyIndex);
-  const Property::Type destinationType = relativeValue.GetType();
+  Object&              object       = GetImplementation(target.object);
+  const Property::Type propertyType = (target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? object.GetPropertyType(target.propertyIndex) : Property::FLOAT;
 
-  // validate animation parameters, if component index is set then use float as checked type
-  ValidateParameters((target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? propertyType : Property::FLOAT,
-                     destinationType,
-                     period);
+  // validate and convert animation parameters, if component index is set then use float as checked type
+  ValidateAndConvertParameters(propertyType, period, relativeValue);
 
   ExtendDuration(period);
 
   // keep the current count.
   auto connectorIndex = mConnectors.Count();
 
-  // using destination type so component animation gets correct type
-  switch(destinationType)
+  switch(propertyType)
   {
     case Property::BOOLEAN:
     {
@@ -688,22 +685,18 @@ void Animation::AnimateTo(Property& target, Property::Value destinationValue, Ti
 
 void Animation::AnimateTo(Property& target, Property::Value destinationValue, AlphaFunction alpha, TimePeriod period)
 {
-  Object&              object          = GetImplementation(target.object);
-  const Property::Type propertyType    = object.GetPropertyType(target.propertyIndex);
-  const Property::Type destinationType = destinationValue.GetType();
+  Object&              object       = GetImplementation(target.object);
+  const Property::Type propertyType = (target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? object.GetPropertyType(target.propertyIndex) : Property::FLOAT;
 
-  // validate animation parameters, if component index is set then use float as checked type
-  ValidateParameters((target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? propertyType : Property::FLOAT,
-                     destinationType,
-                     period);
+  // validate and convert animation parameters, if component index is set then use float as checked type
+  ValidateAndConvertParameters(propertyType, period, destinationValue);
 
   ExtendDuration(period);
 
   // keep the current count.
   auto connectorIndex = mConnectors.Count();
 
-  // using destination type so component animation gets correct type
-  switch(destinationType)
+  switch(propertyType)
   {
     case Property::BOOLEAN:
     {
@@ -831,20 +824,36 @@ void Animation::AnimateBetween(Property target, Dali::KeyFrames keyFrames, Alpha
   Object&          object        = GetImplementation(target.object);
   const KeyFrames& keyFramesImpl = GetImplementation(keyFrames);
 
-  const Property::Type propertyType    = object.GetPropertyType(target.propertyIndex);
-  const Property::Type destinationType = keyFramesImpl.GetType();
+  const Property::Type propertyType = (target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? object.GetPropertyType(target.propertyIndex) : Property::FLOAT;
+
+  auto lastKeyFrameValue = keyFramesImpl.GetLastKeyFrameValue();
+  ValidateAndConvertParameters(propertyType, period, lastKeyFrameValue);
+
+  if(DALI_UNLIKELY(propertyType != keyFramesImpl.GetType()))
+  {
+    // Test for conversion valid, and convert keyframe values to matched property type.
+    Dali::KeyFrames convertedKeyFrames = Dali::KeyFrames::New();
+    auto            keyFrameCount      = keyFramesImpl.GetKeyFrameCount();
+    for(auto frameIndex = 0u; frameIndex < keyFrameCount; ++frameIndex)
+    {
+      float           progress;
+      Property::Value value;
+      keyFramesImpl.GetKeyFrame(frameIndex, progress, value);
+      DALI_ASSERT_ALWAYS(value.ConvertType(propertyType) && "Target types could not be convert to Property type");
 
-  // validate animation parameters, if component index is set then use float as checked type
-  ValidateParameters((target.componentIndex == Property::INVALID_COMPONENT_INDEX) ? propertyType : Property::FLOAT,
-                     destinationType,
-                     period);
+      convertedKeyFrames.Add(progress, value);
+    }
+
+    // Retry to animation as the converted keyframes.
+    AnimateBetween(target, convertedKeyFrames, alpha, period, interpolation);
+    return;
+  }
 
   ExtendDuration(period);
 
-  AppendConnectorTargetValues({keyFramesImpl.GetLastKeyFrameValue(), period, mConnectors.Count(), BETWEEN});
+  AppendConnectorTargetValues({lastKeyFrameValue, period, mConnectors.Count(), BETWEEN});
 
-  // using destination type so component animation gets correct type
-  switch(destinationType)
+  switch(propertyType)
   {
     case Dali::Property::BOOLEAN:
     {
index 3b53f48912a1560fdb6401bfea445ed32a00378d..fd56538e772b61a76df0737b171e0db5715fa446 100644 (file)
@@ -593,6 +593,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
                                                 const Rect<int>&                    rootClippingRect,
                                                 int                                 orientation,
                                                 const Uint16Pair&                   sceneSize,
+                                                Graphics::RenderPass*               renderPass,
                                                 Graphics::RenderTarget*             renderTarget)
 {
   DALI_PRINT_RENDER_LIST(renderList);
@@ -616,7 +617,9 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
 
   // We are always "inside" a render pass here.
   Graphics::CommandBufferBeginInfo info;
-  info.usage = 0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT;
+  info.SetUsage(0 | Graphics::CommandBufferUsageFlagBits::RENDER_PASS_CONTINUE)
+    .SetRenderPass(*renderPass)
+    .SetRenderTarget(*renderTarget);
   secondaryCommandBuffer.Begin(info);
 
   secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(sceneSize, mViewportRectangle, orientation));
@@ -720,7 +723,7 @@ RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController)
 {
 }
 
-void RenderAlgorithms::ResetCommandBuffer()
+void RenderAlgorithms::ResetCommandBuffer(std::vector<Graphics::CommandBufferResourceBinding>* resourceBindings)
 {
   // Reset main command buffer
   if(!mGraphicsCommandBuffer)
@@ -736,7 +739,8 @@ void RenderAlgorithms::ResetCommandBuffer()
   }
 
   Graphics::CommandBufferBeginInfo info;
-  info.usage = 0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT;
+  info.resourceBindings = resourceBindings; // set resource bindings, currently only programs
+  info.usage            = 0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT;
   mGraphicsCommandBuffer->Begin(info);
 }
 
@@ -764,6 +768,7 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&
                                                 const Rect<int>&                    rootClippingRect,
                                                 int                                 orientation,
                                                 const Uint16Pair&                   sceneSize,
+                                                Graphics::RenderPass*               renderPass,
                                                 Graphics::RenderTarget*             renderTarget)
 {
   DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS", [&](std::ostringstream& oss) { oss << "[" << instruction.RenderListCount() << "]"; });
@@ -800,6 +805,7 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&
                           rootClippingRect,
                           orientation,
                           sceneSize,
+                          renderPass,
                           renderTarget);
 
         // Execute command buffer
index 8f91964040e2fe27c54821de7bb598206ebb7340..7acbad1acae82f519f48d512913b74cc69f94d1e 100644 (file)
@@ -71,12 +71,15 @@ public:
                                 const Rect<int>&                     rootClippingRect,
                                 int                                  orientation,
                                 const Uint16Pair&                    sceneSize,
+                                Graphics::RenderPass*                renderPass,
                                 Graphics::RenderTarget*              renderTarget);
 
   /**
    * Resets main command buffer (per scene)
+   *
+   * @param[in] bindings list of resource bindings (optional, can be null)
    */
-  void ResetCommandBuffer();
+  void ResetCommandBuffer(std::vector<Graphics::CommandBufferResourceBinding>* bindings);
 
   /**
    * Submits main command buffer (per scene)
@@ -166,6 +169,7 @@ private:
                                 const Rect<int>&                                     rootClippingRect,
                                 int                                                  orientation,
                                 const Uint16Pair&                                    sceneSize,
+                                Graphics::RenderPass*                                renderPass,
                                 Graphics::RenderTarget*                              renderTarget);
 
   // Member variables:
index 4f72d397ce79a5b87ed3aae3454f22b52bd4107b..42b8652e8a63f9801739fce8e711e6473c4b3858 100644 (file)
@@ -960,11 +960,6 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     return;
   }
 
-  // Reset main algorithms command buffer
-  mImpl->renderAlgorithms.ResetCommandBuffer();
-
-  auto mainCommandBuffer = mImpl->renderAlgorithms.GetMainCommandBuffer();
-
   Internal::Scene&   sceneInternal = GetImplementation(scene);
   SceneGraph::Scene* sceneObject   = sceneInternal.GetSceneObject();
   if(!sceneObject)
@@ -991,6 +986,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
   auto totalSizeCPU = 0u;
   auto totalSizeGPU = 0u;
 
+  std::unordered_map<Graphics::Program*, Graphics::ProgramResourceBindingInfo> programUsageCount;
+
   for(uint32_t i = 0; i < instructionCount; ++i)
   {
     RenderInstruction& instruction = sceneObject->GetRenderInstructions().At(mImpl->renderBufferIndex, i);
@@ -1012,6 +1009,18 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
             {
               const auto& memoryRequirements = program->GetUniformBlocksMemoryRequirements();
 
+              // collect how many programs we use in this frame
+              auto key = &program->GetGraphicsProgram();
+              auto it  = programUsageCount.find(key);
+              if(it == programUsageCount.end())
+              {
+                programUsageCount[key] = Graphics::ProgramResourceBindingInfo{.program = key, .count = 1};
+              }
+              else
+              {
+                (*it).second.count++;
+              }
+
               totalSizeCPU += memoryRequirements.totalCpuSizeRequired;
               totalSizeGPU += memoryRequirements.totalGpuSizeRequired;
             }
@@ -1021,6 +1030,24 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     }
   }
 
+  // Fill resource binding for the command buffer
+  std::vector<Graphics::CommandBufferResourceBinding> commandBufferResourceBindings;
+  if(!programUsageCount.empty())
+  {
+    commandBufferResourceBindings.resize(programUsageCount.size());
+    auto iter = commandBufferResourceBindings.begin();
+    for(auto& item : programUsageCount)
+    {
+      iter->type           = Graphics::ResourceType::PROGRAM;
+      iter->programBinding = &item.second;
+    }
+  }
+
+  // Reset main algorithms command buffer
+  mImpl->renderAlgorithms.ResetCommandBuffer(commandBufferResourceBindings.empty() ? nullptr : &commandBufferResourceBindings);
+
+  auto mainCommandBuffer = mImpl->renderAlgorithms.GetMainCommandBuffer();
+
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Render scene (%s), CPU:%d GPU:%d\n", renderToFbo ? "Offscreen" : "Onscreen", totalSizeCPU, totalSizeGPU);
 
   auto& uboManager = mImpl->uniformBufferManager;
@@ -1243,6 +1270,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
       clippingRect,
       surfaceOrientation,
       Uint16Pair(surfaceRect.width, surfaceRect.height),
+      currentRenderPass,
       currentRenderTarget);
 
     Graphics::SyncObject* syncObject{nullptr};
index e48c5534d798fdd9a52584df7b74a04c3b215a3b..8743c3374aedbfaba239d7c2b997c52d94e7a60f 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 3;
-const uint32_t    CORE_MICRO_VERSION = 41;
+const uint32_t    CORE_MICRO_VERSION = 42;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 79381b40f0ae2efbaa2696cba3842440151b063a..f1c63321280ec2725cba479897558b568ef0d381 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -500,6 +500,106 @@ struct Property::Value::Impl
     mData.mType.type = typeValue;
   }
 
+  bool ConvertType(const Property::Type targetType)
+  {
+    bool                 converted = false;
+    const Property::Type inputType = mData.mType.type;
+
+    if(inputType == targetType)
+    {
+      // We don't need conversion for same type.
+      return true;
+    }
+
+    switch(inputType)
+    {
+      // Try to convert only for scalar types
+      case Property::BOOLEAN:
+      {
+        bool value = mData.mBool.member;
+        switch(targetType)
+        {
+          case Property::FLOAT:
+          {
+            SetType(targetType);
+            mData.mFloat.member = static_cast<float>(value);
+            converted           = true;
+            break;
+          }
+          case Property::INTEGER:
+          {
+            SetType(targetType);
+            mData.mInt.member = static_cast<int32_t>(value);
+            converted         = true;
+            break;
+          }
+          default:
+          {
+            break;
+          }
+        }
+        break;
+      }
+      case Property::FLOAT:
+      {
+        float value = mData.mFloat.member;
+        switch(targetType)
+        {
+          case Property::BOOLEAN:
+          {
+            SetType(targetType);
+            mData.mBool.member = static_cast<bool>(!Dali::EqualsZero(value));
+            converted          = true;
+            break;
+          }
+          case Property::INTEGER:
+          {
+            SetType(targetType);
+            mData.mInt.member = static_cast<int32_t>(value);
+            converted         = true;
+            break;
+          }
+          default:
+          {
+            break;
+          }
+        }
+        break;
+      }
+      case Property::INTEGER:
+      {
+        int32_t value = mData.mInt.member;
+        switch(targetType)
+        {
+          case Property::BOOLEAN:
+          {
+            SetType(targetType);
+            mData.mBool.member = static_cast<bool>(value);
+            converted          = true;
+            break;
+          }
+          case Property::FLOAT:
+          {
+            SetType(targetType);
+            mData.mFloat.member = static_cast<float>(value);
+            converted           = true;
+            break;
+          }
+          default:
+          {
+            break;
+          }
+        }
+        break;
+      }
+      default:
+      {
+        break;
+      }
+    }
+    return converted;
+  }
+
 private:
   /**
    * This helper function takes a typed(Tp) memory location( member)
@@ -917,6 +1017,11 @@ Property::Type Property::Value::GetType() const
   return Read().GetType();
 }
 
+bool Property::Value::ConvertType(const Property::Type targetType)
+{
+  return Write().ConvertType(targetType);
+}
+
 bool Property::Value::Get(bool& booleanValue) const
 {
   bool converted = false;
index 5260f4f3560878dc61fa51b005d1a6a91a2b7235..74eea20ca03b55af55dfaa090221477bc0bd042d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_PROPERTY_VALUE_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.
@@ -299,6 +299,16 @@ public:
    */
   Type GetType() const;
 
+  /**
+   * @brief Convert value to another type.
+   * @note It will be works only if both input and output are scalar type. - Property::BOOLEAN, Property::FLOAT, Property::INTEGER.
+   *
+   * @SINCE_2_3.41
+   * @param[in] targetType Target type of the conversion.
+   * @return True if convert is successful, false otherwise. If the conversion fails, the original value is not modified.
+   */
+  bool ConvertType(const Property::Type targetType);
+
   /**
    * @brief Retrieves a specific value.
    *
index 6e96d0d3b2c1be5da82720b052484bb8cbd0415b..bd0cf0420f8f5bcd7f9a678fead8c203ff9e531b 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.3.41
+Version:    2.3.42
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT