Merge branch 'devel/master' into tizen
authorEverLEEst(SangHyeon Lee) <sh10233.lee@samsung.com>
Wed, 28 Jun 2023 05:39:17 +0000 (14:39 +0900)
committerEverLEEst(SangHyeon Lee) <sh10233.lee@samsung.com>
Wed, 28 Jun 2023 05:39:17 +0000 (14:39 +0900)
48 files changed:
automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp
automated-tests/src/dali-scene3d/CMakeLists.txt
automated-tests/src/dali-scene3d/utc-Dali-SceneView.cpp
automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-buffer.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-buffer.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-program.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-program.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-reflection.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-reflection.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-texture.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard-event-notifier.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.h
automated-tests/src/dali-toolkit/utc-Dali-ParticleSystem.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.vert
dali-scene3d/internal/model-components/material-impl.cpp
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/public-api/file.list
dali-scene3d/public-api/loader/shader-definition-factory.cpp
dali-scene3d/public-api/loader/shader-definition-option.cpp [new file with mode: 0644]
dali-scene3d/public-api/loader/shader-definition-option.h [new file with mode: 0644]
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/particle-system/particle-emitter-impl.cpp
dali-toolkit/internal/particle-system/particle-emitter-impl.h
dali-toolkit/internal/particle-system/particle-renderer-impl.cpp
dali-toolkit/internal/particle-system/particle-renderer-impl.h
dali-toolkit/internal/text/controller/text-controller-event-handler.cpp
dali-toolkit/internal/text/controller/text-controller-impl.h
dali-toolkit/internal/visuals/svg/svg-task.cpp
dali-toolkit/internal/visuals/svg/svg-task.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 088bb6f..34a82b2 100644 (file)
  *
  */
 
-#include <toolkit-event-thread-callback.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <stdlib.h>
+#include <toolkit-event-thread-callback.h>
 #include <iostream>
 
-#include <dali-scene3d/internal/model-components/material-impl.h>
 #include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-scene3d/internal/model-components/material-impl.h>
+#include <dali-scene3d/public-api/loader/shader-definition-option.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -96,11 +97,11 @@ int UtcDaliMaterialImplSetGetTextureInformation(void)
   GetImplementation(material).UpdateMaterialData();
 
   std::vector<std::string> defines;
-  defines.push_back("THREE_TEX");
-  defines.push_back("GLTF_CHANNELS");
-  defines.push_back("BASECOLOR_TEX");
-  defines.push_back("METALLIC_ROUGHNESS_TEX");
-  defines.push_back("NORMAL_TEX");
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE).data());
 
   std::string fragmentShader = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
   for(const auto& define : defines)
@@ -175,10 +176,10 @@ int UtcDaliMaterialImplSetGetTextureInformation(void)
   DALI_TEST_EQUALS(true, GetImplementation(material).IsResourceReady(), TEST_LOCATION);
   GetImplementation(material).UpdateMaterialData();
 
-  defines.push_back("OCCLUSION");
-  defines.push_back("EMISSIVE");
-  defines.push_back("MATERIAL_SPECULAR_TEXTURE");
-  defines.push_back("MATERIAL_SPECULAR_COLOR_TEXTURE");
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR).data());
+  defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR).data());
 
   fragmentShader = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
   for(const auto& define : defines)
index 29b6775..4dff80c 100755 (executable)
@@ -31,6 +31,7 @@ SET(TC_SOURCES
   utc-Dali-SceneDefinition.cpp
   utc-Dali-ShaderDefinition.cpp
   utc-Dali-ShaderDefinitionFactory.cpp
+  utc-Dali-ShaderDefinitionOption.cpp
   utc-Dali-StringCallback.cpp
   utc-Dali-Utils.cpp
   utc-Dali-ViewProjection.cpp
index caaca31..53e7725 100644 (file)
@@ -882,6 +882,38 @@ int UtcDaliSceneViewSetSkyboxEmpty(void)
   END_TEST;
 }
 
+int UtcDaliSceneViewSetSkyboxEmpty2(void)
+{
+  ToolkitTestApplication application;
+
+  gResourceReadyCalled    = false;
+  Scene3D::SceneView view = Scene3D::SceneView::New();
+  view.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  view.ResourceReadySignal().Connect(OnResourceReady);
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  view.SetSkybox(TEST_EQUIRECTANGULAR_TEXTURE);
+
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  application.SendNotification();
+  application.Render();
+
+  uint32_t childCount = view.GetChildAt(0u).GetChildCount();
+
+  view.SetSkybox("");
+  DALI_TEST_EQUALS(view.GetChildAt(0u).GetChildCount(), childCount - 1, TEST_LOCATION);
+
+  view.Unparent();
+  view.Reset();
+
+  END_TEST;
+}
+
 int UtcDaliSceneViewSetSkyboxEquirectangularEmpty(void)
 {
   ToolkitTestApplication application;
diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp
new file mode 100644 (file)
index 0000000..0f320a8
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <string_view>
+#include "dali-scene3d/public-api/loader/shader-definition-option.h"
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+void shader_definition_option_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void shader_definition_option_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliShaderDefinitionOptionInit(void)
+{
+  Scene3D::Loader::ShaderDefinitionOption option;
+  DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION);
+  END_TEST;
+}
+
+int UtcDaliShaderDefinitionOptionSetTransparency(void)
+{
+  Scene3D::Loader::ShaderDefinitionOption option;
+  DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION);
+
+  option.SetTransparency();
+  DALI_TEST_NOT_EQUALS(option.GetOptionHash(), static_cast<uint64_t>(0u), 0.1f, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliShaderDefinitionOptionAddOption(void)
+{
+  Scene3D::Loader::ShaderDefinitionOption option;
+  DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION);
+
+  Scene3D::Loader::ShaderDefinitionOption::Type types[19] = {
+    Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS,
+    Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION,
+    Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::ALPHA_TEST,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SUBSURFACE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SKINNING,
+    Scene3D::Loader::ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL,
+    Scene3D::Loader::ShaderDefinitionOption::Type::COLOR_ATTRIBUTE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::VEC4_TANGENT,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_POSITION,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_NORMAL,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_TANGENT,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_VERSION_2_0};
+
+  uint64_t hash = 0u;
+  for(uint32_t i = 0; i < 19; ++i)
+  {
+    hash |= (1 << static_cast<uint32_t>(types[i]));
+    option.AddOption(types[i]);
+    DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
+int UtcDaliShaderDefinitionOptionGetDefines(void)
+{
+  Scene3D::Loader::ShaderDefinitionOption option;
+  DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION);
+
+  Scene3D::Loader::ShaderDefinitionOption::Type types[19] = {
+    Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS,
+    Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION,
+    Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::ALPHA_TEST,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SUBSURFACE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR,
+    Scene3D::Loader::ShaderDefinitionOption::Type::SKINNING,
+    Scene3D::Loader::ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL,
+    Scene3D::Loader::ShaderDefinitionOption::Type::COLOR_ATTRIBUTE,
+    Scene3D::Loader::ShaderDefinitionOption::Type::VEC4_TANGENT,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_POSITION,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_NORMAL,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_TANGENT,
+    Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_VERSION_2_0};
+
+  uint64_t hash = 0u;
+  for(uint32_t i = 0; i < 19; ++i)
+  {
+    hash |= (1 << static_cast<uint32_t>(types[i]));
+    option.AddOption(types[i]);
+    DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION);
+
+    std::vector<std::string> defines;
+    option.GetDefines(defines);
+    DALI_TEST_EQUALS(defines.size(), i + 1, TEST_LOCATION);
+    for(uint32_t j = 0; j < defines.size(); ++j)
+    {
+      DALI_TEST_EQUALS(defines[j], option.GetDefineKeyword(types[j]), TEST_LOCATION);
+    }
+  }
+
+  END_TEST;
+}
\ No newline at end of file
index a1e3c6e..dd5ec2f 100644 (file)
@@ -45,7 +45,7 @@ const char* const OPTION_CLIPBOARD("optionClipboard");    // "Clipboard" popup o
 const Size CONTROL_SIZE(300.f, 60.f);
 
 std::string gClipboardText;
-void        ContentSelectedCallback(ClipboardEventNotifier& notifier)
+void        ContentSelectedCallback(TextClipboardEventNotifier& notifier)
 {
   gClipboardText = notifier.GetContent();
 }
@@ -547,7 +547,7 @@ int UtcDaliTextControllerTextPopupButtonTouched(void)
   controller->GetText(text);
   DALI_TEST_CHECK(text.empty());
 
-  ClipboardEventNotifier clipboardEventNotifier = ClipboardEventNotifier::Get();
+  TextClipboardEventNotifier clipboardEventNotifier = TextClipboardEventNotifier::Get();
   clipboardEventNotifier.ContentSelectedSignal().Connect(&ContentSelectedCallback);
 
   // Paste the text.
index eb1ab88..d628f0d 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/dali-core.h>
 
 // INTERNAL INCLUDES
+#include <dali-test-suite-utils.h>
 #include "mesh-builder.h"
 
 namespace Dali
@@ -138,4 +139,29 @@ TextureSet CreateTextureSet(Pixel::Format format, int width, int height)
   return textureSet;
 }
 
+void DirtyRectChecker(const std::vector<Rect<int>>& damagedRects, std::multiset<Rect<int>, RectSorter> expectedRectList, bool checkRectsExact, const char* testLocation)
+{
+  // Just check damagedRect contain all expectRectList.
+  DALI_TEST_GREATER(damagedRects.size() + 1u, expectedRectList.size(), testLocation);
+
+  for(auto& rect : damagedRects)
+  {
+    auto iter = expectedRectList.find(rect);
+    if(iter != expectedRectList.end())
+    {
+      expectedRectList.erase(iter);
+    }
+    else if(checkRectsExact)
+    {
+      std::ostringstream o;
+      o << rect << " exist in expectRectList" << std::endl;
+      fprintf(stderr, "Test failed in %s, checking %s", testLocation, o.str().c_str());
+      tet_result(TET_FAIL);
+    }
+  }
+
+  // Check all rects are matched
+  DALI_TEST_EQUALS(expectedRectList.empty(), true, testLocation);
+}
+
 } // namespace Dali
index 94f1493..6571365 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali/public-api/rendering/texture.h>
+#include <set> // For std::multiset
 #include <string>
 
 namespace Dali
@@ -63,6 +64,30 @@ Actor CreateRenderableActor2(TextureSet textures, const std::string& vertexShade
 Texture    CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height);
 TextureSet CreateTextureSet(Pixel::Format format, int width, int height);
 
+// Check dirtyRect is equal with expected multiset.
+// Note that the order of damagedRect is not important
+struct RectSorter
+{
+  bool operator()(const Rect<int>& lhs, const Rect<int>& rhs) const
+  {
+    if(lhs.x != rhs.x)
+    {
+      return lhs.x < rhs.x;
+    }
+    if(lhs.y != rhs.y)
+    {
+      return lhs.y < rhs.y;
+    }
+    if(lhs.width != rhs.width)
+    {
+      return lhs.width < rhs.width;
+    }
+    return lhs.height < rhs.height;
+  }
+};
+
+void DirtyRectChecker(const std::vector<Rect<int>>& damagedRects, std::multiset<Rect<int>, RectSorter> expectedRectList, bool checkRectsExact, const char* testLocation);
+
 } // namespace Dali
 
 #endif // DALI_TEST_ACTOR_UTILS_H
index 1d20a6a..38169a2 100644 (file)
 #include "test-gl-abstraction.h"
 #include "test-trace-call-stack.h"
 
-static const bool TRACE{
-  false};
+static const bool TRACE{false};
+
+uint32_t GetGLDataTypeSize(GLenum type)
+{
+  // There are many more types than what are covered here, but
+  // they are not supported in dali.
+  switch(type)
+  {
+    case GL_FLOAT: // "float", 1 float, 4 bytes
+      return 4;
+    case GL_FLOAT_VEC2: // "vec2", 2 floats, 8 bytes
+      return 8;
+    case GL_FLOAT_VEC3: // "vec3", 3 floats, 12 bytes
+      return 12;
+    case GL_FLOAT_VEC4: // "vec4", 4 floats, 16 bytes
+      return 16;
+    case GL_INT: // "int", 1 integer, 4 bytes
+      return 4;
+    case GL_FLOAT_MAT2: // "mat2", 4 floats, 16 bytes
+      return 16;
+    case GL_FLOAT_MAT3: // "mat3", 3 vec3, 36 bytes
+      return 36;
+    case GL_FLOAT_MAT4: // "mat4", 4 vec4, 64 bytes
+      return 64;
+    default:
+      return 0;
+  }
+}
 
 namespace Dali
 {
@@ -145,6 +171,12 @@ void TestGlAbstraction::Initialize()
     {"uLightCameraProjectionMatrix", GL_FLOAT_MAT4, 1},
     {"uLightCameraViewMatrix", GL_FLOAT_MAT4, 1}};
 
+  int offset = 0;
+  for(uint32_t i = 0; i < mActiveUniforms.size(); ++i)
+  {
+    mActiveUniforms[i].offset = offset;
+    offset += mActiveUniforms[i].size * GetGLDataTypeSize(mActiveUniforms[i].type);
+  }
   // WARNING: IF YOU CHANGE THIS LIST, ALSO CHANGE UNIFORMS IN test-graphics-reflection.cpp
 }
 
@@ -196,6 +228,17 @@ bool TestGlAbstraction::TextureRequiresConverting(const GLenum imageGlFormat, co
   return ((imageGlFormat == GL_RGB) && (textureGlFormat == GL_RGBA));
 }
 
+void TestGlAbstraction::SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
+{
+  mActiveUniforms = uniforms;
+  int offset      = 0;
+  for(uint32_t i = 0; i < uniforms.size(); ++i)
+  {
+    mActiveUniforms[i].offset = offset;
+    offset += mActiveUniforms[i].size * GetGLDataTypeSize(mActiveUniforms[i].type);
+  }
+}
+
 } // namespace Dali
 
 bool BlendEnabled(const Dali::TraceCallStack& callStack)
index cc27d9e..2ca98dc 100644 (file)
@@ -51,9 +51,10 @@ struct UniformData
 
 struct ActiveUniform
 {
-  std::string name;
-  GLenum      type;
-  GLint       size;
+  std::string name{};
+  GLenum      type{GL_FLOAT};
+  GLint       size{0};
+  GLint       offset{0};
 };
 
 class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
@@ -457,6 +458,10 @@ public:
 
   inline void DeleteBuffers(GLsizei n, const GLuint* buffers) override
   {
+    TraceCallStack::NamedParams namedParams;
+    namedParams["n"] << n;
+    namedParams["id"] << buffers[0];
+    mBufferTrace.PushCall("DeleteBuffers", namedParams.str(), namedParams);
   }
 
   inline void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override
@@ -697,13 +702,21 @@ public:
   inline void GenBuffers(GLsizei n, GLuint* buffers) override
   {
     // avoids an assert in GpuBuffers
-    *buffers = 1u;
+    static GLuint id = 1;
 
-    std::ostringstream o;
-    o << n;
     TraceCallStack::NamedParams namedParams;
-    namedParams["n"] << o.str();
-    mBufferTrace.PushCall("GenBuffers", o.str(), namedParams);
+    namedParams["n"] << n;
+
+    // Allocate some buffer names
+    bool first = true;
+    while(n)
+    {
+      namedParams["buffers"] << (first ? "" : ", ") << id;
+      first      = false;
+      *buffers++ = id++;
+      --n;
+    }
+    mBufferTrace.PushCall("GenBuffers", namedParams.str(), namedParams);
   }
 
   inline void GenerateMipmap(GLenum target) override
@@ -800,10 +813,7 @@ public:
     *type = mAttribTypes[index];
   }
 
-  inline void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
-  {
-    mActiveUniforms = uniforms;
-  }
+  void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms);
 
   inline void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
   {
@@ -865,6 +875,9 @@ public:
       case GL_PROGRAM_BINARY_FORMATS_OES:
         *params = mBinaryFormats;
         break;
+      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+        *params = mUniformBufferOffsetAlignment;
+        break;
     }
   }
 
@@ -1882,6 +1895,44 @@ public:
 
   inline void GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) override
   {
+    for(int i = 0; i < uniformCount; ++i)
+    {
+      if(i < int(mActiveUniforms.size()))
+      {
+        switch(pname)
+        {
+          case GL_UNIFORM_TYPE:
+          {
+            params[i] = mActiveUniforms[i].type;
+            break;
+          }
+          case GL_UNIFORM_SIZE:
+          {
+            params[i] = mActiveUniforms[i].size;
+            break;
+          }
+          case GL_UNIFORM_NAME_LENGTH:
+          {
+            params[i] = mActiveUniforms[i].name.length();
+            break;
+          }
+          case GL_UNIFORM_BLOCK_INDEX:
+          {
+            params[i] = -1;
+            break;
+          }
+          case GL_UNIFORM_OFFSET:
+          {
+            params[i] = mActiveUniforms[i].offset;
+            break;
+          }
+          case GL_UNIFORM_MATRIX_STRIDE:
+          {
+            break;
+          }
+        }
+      }
+    }
   }
 
   inline GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) override
@@ -2169,7 +2220,10 @@ public: // TEST FUNCTIONS
   {
     mProgramBinaryLength = length;
   }
-
+  inline void SetUniformBufferOffsetAlignment(GLint align)
+  {
+    mUniformBufferOffsetAlignment = align;
+  }
   inline bool GetVertexAttribArrayState(GLuint index)
   {
     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
@@ -2582,6 +2636,7 @@ public:
   GLint                                 mNumBinaryFormats;
   GLint                                 mBinaryFormats;
   GLint                                 mProgramBinaryLength;
+  GLint                                 mUniformBufferOffsetAlignment{1};
   bool                                  mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
   bool                                  mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
   bool                                  mGetProgramBinaryCalled;
index 42b53b1..456d978 100644 (file)
 
 namespace Dali
 {
-TestGraphicsBuffer::TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage)
+TestGraphicsBuffer::TestGraphicsBuffer(const Graphics::BufferCreateInfo& createInfo, TestGraphicsController& controller, TestGlAbstraction& glAbstraction, TraceCallStack& callStack)
 : mCallStack(callStack),
+  mController(controller),
   mGl(glAbstraction),
-  mUsage(usage)
+  mCreateInfo(createInfo),
+  mUsage(createInfo.usage)
 {
-  memory.resize(size);
-  mGl.GetBufferTrace().EnableLogging(false);
+  if(createInfo.propertiesFlags & int(Graphics::BufferPropertiesFlagBit::CPU_ALLOCATED))
+  {
+    mCpuOnly = true;
+  }
+  else
+  {
+    mGl.GenBuffers(1, &mId);
+  }
+  memory.resize(createInfo.size);
+}
+
+TestGraphicsBuffer::~TestGraphicsBuffer()
+{
+  // Not strictly parameters, but useful for testing
+  TraceCallStack::NamedParams namedParams;
+  namedParams["usage"] << "0x" << std::hex << mCreateInfo.usage;
+  namedParams["propertiesFlags"] << mCreateInfo.propertiesFlags;
+
+  mCallStack.PushCall("Buffer::~Buffer", namedParams.str(), namedParams);
+  if(!mCpuOnly && mId)
+  {
+    mGl.DeleteBuffers(1, &mId);
+  }
+}
+
+void TestGraphicsBuffer::DiscardResource()
+{
+  mController.DiscardBuffer(this);
 }
 
 void TestGraphicsBuffer::Bind()
 {
   mCallStack.PushCall("Buffer::Bind", "");
-  if(!mId)
+  if(!mCpuOnly && mId > 0)
   {
-    mGl.GenBuffers(1, &mId);
+    mGl.BindBuffer(GetTarget(), mId);
   }
-  mGl.BindBuffer(GetTarget(), mId);
 }
 
 void TestGraphicsBuffer::Unbind()
 {
   mCallStack.PushCall("Buffer::Unbind", "");
-  if(mId)
+  if(!mCpuOnly)
   {
-    mGl.BindBuffer(GetTarget(), 0);
+    if(mId)
+    {
+      mGl.BindBuffer(GetTarget(), 0);
+    }
   }
 }
 
@@ -58,15 +88,19 @@ void TestGraphicsBuffer::Upload(uint32_t offset, uint32_t size)
   namedParams["offset"] << offset;
   namedParams["size"] << size;
   mCallStack.PushCall("Buffer::Upload", o.str(), namedParams);
-  if(size <= memory.size() && mCreated)
-  {
-    // Use subData to avoid re-allocation
-    mGl.BufferSubData(GetTarget(), static_cast<GLintptr>(static_cast<unsigned long>(offset)), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[offset]);
-  }
-  else
+
+  if(!mCpuOnly)
   {
-    mGl.BufferData(GetTarget(), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages?
-    mCreated = true;
+    if(size <= memory.size() && mCreated)
+    {
+      // Use subData to avoid re-allocation
+      mGl.BufferSubData(GetTarget(), static_cast<GLintptr>(static_cast<unsigned long>(offset)), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[offset]);
+    }
+    else
+    {
+      mGl.BufferData(GetTarget(), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages?
+      mCreated = true;
+    }
   }
 }
 
index 1dc2715..220ae06 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_GRAPHICS_BUFFER_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -17,6 +17,7 @@
  * limitations under the License.
  */
 
+#include <dali/graphics-api/graphics-buffer-create-info.h>
 #include <dali/graphics-api/graphics-buffer.h>
 #include <dali/graphics-api/graphics-types.h>
 
 namespace Dali
 {
 class TestGraphicsProgram;
+class TestGraphicsController;
 class UniformBufferBindingDescriptor;
+
 class TestGraphicsBuffer : public Graphics::Buffer
 {
 public:
-  TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage);
+  TestGraphicsBuffer(const Graphics::BufferCreateInfo& createInfo, TestGraphicsController& controller, TestGlAbstraction& glAbstraction, TraceCallStack& callStack);
+  ~TestGraphicsBuffer();
+  void DiscardResource();
+
   void   Bind();
   void   Unbind();
   void   Upload(uint32_t offset, uint32_t size);
@@ -38,17 +44,21 @@ public:
 
   bool IsCPUAllocated() const
   {
-    return true;
+    return mCpuOnly;
   }
 
   void BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const;
 
-  TraceCallStack&            mCallStack;
-  TestGlAbstraction&         mGl;
-  std::vector<uint8_t>       memory;
+  TraceCallStack&         mCallStack;
+  TestGraphicsController& mController;
+  TestGlAbstraction&      mGl;
+  std::vector<uint8_t>    memory;
+
+  Graphics::BufferCreateInfo mCreateInfo;
   Graphics::BufferUsageFlags mUsage;
   GLuint                     mId{0};
   bool                       mCreated{false};
+  bool                       mCpuOnly{false};
 };
 
 } // namespace Dali
index 14c6d50..4bac7a6 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "test-graphics-controller.h"
 
+#include <dali/graphics-api/graphics-types.h>
 #include "test-graphics-buffer.h"
 #include "test-graphics-command-buffer.h"
 #include "test-graphics-framebuffer.h"
 #include "test-graphics-texture.h"
 
 #include <dali/integration-api/gl-defines.h>
+#include <any>
 #include <cstdio>
 #include <iostream>
+#include <memory>
 #include <sstream>
 
-#include <any>
-
 namespace Dali
 {
+namespace
+{
+template<class T>
+struct TestGraphicsDeleter
+{
+  TestGraphicsDeleter() = default;
+  void operator()(T* object)
+  {
+    // Discard resource
+    object->DiscardResource();
+  }
+};
+
+} //namespace
+
 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
 {
   return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
@@ -1185,10 +1201,25 @@ bool TestGraphicsController::IsDrawOnResumeRequired()
 
 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
 {
-  std::ostringstream oss;
-  oss << "bufferCreateInfo:" << createInfo;
-  mCallStack.PushCall("CreateBuffer", oss.str());
-  return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
+  TraceCallStack::NamedParams namedParams;
+  namedParams["usage"] << "0x" << std::hex << createInfo.usage;
+  namedParams["propertiesFlags"] << createInfo.propertiesFlags;
+  namedParams["size"] << createInfo.size;
+  mCallStack.PushCall("CreateBuffer", namedParams.str(), namedParams);
+
+  auto ptr = Graphics::MakeUnique<TestGraphicsBuffer, TestGraphicsDeleter<TestGraphicsBuffer>>(createInfo, *this, mGl, mCallStack);
+  mAllocatedBuffers.push_back(ptr.get());
+  return ptr;
+}
+
+void TestGraphicsController::DiscardBuffer(TestGraphicsBuffer* buffer)
+{
+  auto iter = std::find(mAllocatedBuffers.begin(), mAllocatedBuffers.end(), buffer);
+  if(iter != mAllocatedBuffers.end())
+  {
+    mAllocatedBuffers.erase(iter);
+  }
+  delete buffer;
 }
 
 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
@@ -1258,7 +1289,8 @@ Graphics::UniquePtr<Graphics::Program> TestGraphicsController::CreateProgram(con
   }
 
   mProgramCache.emplace_back();
-  mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
+  mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms, mCustomUniformBlocks);
+
   for(auto& shader : *(programCreateInfo.shaderState))
   {
     auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
@@ -1329,8 +1361,24 @@ Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirement
 
 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
 {
+  static GLint uniformAlign{0};
+
+  Graphics::MemoryRequirements reqs{};
   mCallStack.PushCall("GetBufferMemoryRequirements", "");
-  return Graphics::MemoryRequirements{};
+
+  auto gfxBuffer = Uncast<TestGraphicsBuffer>(&buffer);
+  if(gfxBuffer->mCreateInfo.usage & (0 | Graphics::BufferUsage::UNIFORM_BUFFER))
+  {
+    if(!uniformAlign)
+    {
+      // Throw off the shackles of constness
+      auto& gl = *const_cast<TestGlAbstraction*>(&mGl);
+      gl.GetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniformAlign);
+    }
+    reqs.size      = gfxBuffer->mCreateInfo.size;
+    reqs.alignment = uint32_t(uniformAlign);
+  }
+  return reqs;
 }
 
 Graphics::TextureProperties TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
index 81b93d2..ade48d7 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_GRAPHICS_CONTROLLER_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -207,6 +207,8 @@ public:
    */
   Graphics::UniquePtr<Graphics::Buffer> CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer) override;
 
+  void DiscardBuffer(TestGraphicsBuffer* buffer);
+
   /**
    * @brief Creates new CommandBuffer object
    *
@@ -384,6 +386,11 @@ public: // Test Functions
     mCustomUniforms = customUniforms;
   }
 
+  void AddCustomUniformBlock(const TestGraphicsReflection::TestUniformBlockInfo& blockInfo)
+  {
+    mCustomUniformBlocks.push_back(blockInfo);
+  }
+
   void ClearSubmitStack()
   {
     mSubmitStack.clear();
@@ -427,11 +434,14 @@ public:
   };
   std::vector<ProgramCache> mProgramCache;
 
+  std::vector<TestGraphicsBuffer*> mAllocatedBuffers;
+
   struct PipelineCache
   {
   };
 
-  std::vector<UniformData> mCustomUniforms;
+  std::vector<UniformData>                                  mCustomUniforms;
+  std::vector<TestGraphicsReflection::TestUniformBlockInfo> mCustomUniformBlocks;
 };
 
 } // namespace Dali
index 8f2e0c7..2706305 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 
 namespace Dali
 {
-TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms)
+TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
 : mGl(gl),
   mId(gl.CreateProgram()),
   mCreateInfo(createInfo),
-  mReflection(gl, mId, vertexFormats, createInfo, customUniforms)
+  mReflection(gl, mId, vertexFormats, createInfo, customUniforms, customUniformBlocks)
 {
   // Ensure active sampler uniforms are set
   mGl.SetCustomUniforms(customUniforms);
index 3899bec..8641800 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_GRAPHICS_PROGRAM_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -27,7 +27,7 @@ namespace Dali
 class TestGraphicsProgramImpl
 {
 public:
-  TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms);
+  TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks);
 
   // For API
   const TestGraphicsReflection& GetReflection() const
index 6cb90ba..2822c0a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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/object/property-map.h>
 #include <string>
 #include <vector>
+
+extern "C"
+{
+  void tet_infoline(const char* str);
+  void tet_printf(const char* format, ...);
+}
+
 namespace Dali
 {
 namespace
@@ -103,7 +110,7 @@ constexpr int GetSizeForType(Property::Type type)
 
 } // namespace
 
-TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms)
+TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
 : mGl(gl),
   mCustomUniforms(customUniforms)
 {
@@ -226,6 +233,10 @@ TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t p
   mDefaultUniformBlock.size = offset;
 
   mUniformBlocks.push_back(mDefaultUniformBlock);
+  for(auto& element : customUniformBlocks)
+  {
+    mUniformBlocks.push_back(element);
+  }
 }
 
 uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& name) const
@@ -247,11 +258,13 @@ uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& n
 
 Dali::Graphics::VertexInputAttributeFormat TestGraphicsReflection::GetVertexAttributeFormat(uint32_t location) const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeFormat is unimplemented\n");
   return Dali::Graphics::VertexInputAttributeFormat{};
 }
 
 std::string TestGraphicsReflection::GetVertexAttributeName(uint32_t location) const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeName is unimplemented\n");
   return 0u;
 }
 
@@ -272,7 +285,11 @@ uint32_t TestGraphicsReflection::GetUniformBlockCount() const
 
 uint32_t TestGraphicsReflection::GetUniformBlockBinding(uint32_t index) const
 {
-  return 0u;
+  if(index >= mUniformBlocks.size())
+  {
+    return 0;
+  }
+  return mUniformBlocks[index].binding;
 }
 
 uint32_t TestGraphicsReflection::GetUniformBlockSize(uint32_t index) const
@@ -316,11 +333,13 @@ bool TestGraphicsReflection::GetUniformBlock(uint32_t index, Dali::Graphics::Uni
 
 std::vector<uint32_t> TestGraphicsReflection::GetUniformBlockLocations() const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockLocations is unimplemented\n");
   return std::vector<uint32_t>{};
 }
 
 std::string TestGraphicsReflection::GetUniformBlockName(uint32_t blockIndex) const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockName is unimplemented\n");
   return std::string{};
 }
 
@@ -362,11 +381,13 @@ uint32_t TestGraphicsReflection::GetUniformBlockMemberOffset(uint32_t blockIndex
 
 bool TestGraphicsReflection::GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetNamedUniform is unimplemented\n");
   return true;
 }
 
 const std::vector<Dali::Graphics::UniformInfo>& TestGraphicsReflection::GetSamplers() const
 {
+  tet_infoline("Warning, TestGraphicsReflection::GetSamplers is unimplemented\n");
   static std::vector<Dali::Graphics::UniformInfo> samplers{};
   return samplers;
 }
index e968bd5..e701e17 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_GRAPHICS_REFLECTION_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -26,7 +26,9 @@ namespace Dali
 class TestGraphicsReflection : public Graphics::Reflection
 {
 public:
-  TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms);
+  class TestUniformBlockInfo;
+
+  TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestUniformBlockInfo>& customUniformBlocks);
 
   uint32_t                                        GetVertexAttributeLocation(const std::string& name) const override;
   Dali::Graphics::VertexInputAttributeFormat      GetVertexAttributeFormat(uint32_t location) const override;
index 782904c..4d86364 100644 (file)
@@ -31,7 +31,7 @@ class TestGraphicsTexture : public Graphics::Texture
 public:
   TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo);
 
-  ~TestGraphicsTexture();
+  ~TestGraphicsTexture() override;
 
   /**
    * Initialize the texture: allocate gl mem, apply default samplers
index 2316036..1284793 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -248,11 +248,15 @@ int TraceCallStack::FindIndexFromMethodAndParams(std::string method, const Trace
 
       for(auto iter = params.mParams.begin(); iter != params.mParams.end(); ++iter)
       {
-        auto        paramIter = mCallStack[i].namedParams.find(iter->parameterName);
-        std::string value     = paramIter->value.str();
-        std::string iValue    = iter->value.str();
-
-        if(paramIter == mCallStack[i].namedParams.end() || value.compare(iValue))
+        auto paramIter = mCallStack[i].namedParams.find(iter->parameterName);
+        if(paramIter == mCallStack[i].namedParams.end())
+        {
+          match = false;
+          break;
+        }
+        std::string value  = paramIter->value.str();
+        std::string iValue = iter->value.str();
+        if(value.compare(iValue))
         {
           match = false;
           break;
index cbfe93e..cfc2a96 100644 (file)
@@ -30,15 +30,15 @@ namespace Internal
 namespace Adaptor
 {
 
-class ClipboardEventNotifier : public Dali::BaseObject
+class TextClipboardEventNotifier : public Dali::BaseObject
 {
 public:
 
-  typedef Dali::ClipboardEventNotifier::ClipboardEventSignalType ClipboardEventSignalType;
+  typedef Dali::TextClipboardEventNotifier::TextClipboardEventSignalType TextClipboardEventSignalType;
 
   // Creation
-  static Dali::ClipboardEventNotifier New();
-  static Dali::ClipboardEventNotifier Get();
+  static Dali::TextClipboardEventNotifier New();
+  static Dali::TextClipboardEventNotifier Get();
 
   // Public API
   const std::string& GetContent() const;
@@ -47,97 +47,97 @@ public:
   void EmitContentSelectedSignal();
 
   // Signals
-  ClipboardEventSignalType& ContentSelectedSignal()
+  TextClipboardEventSignalType& ContentSelectedSignal()
   {
     return mContentSelectedSignal;
   }
 
 private:
   // Construction & Destruction
-  ClipboardEventNotifier();
-  virtual ~ClipboardEventNotifier();
+  TextClipboardEventNotifier();
+  virtual ~TextClipboardEventNotifier();
 
   // Undefined
-  ClipboardEventNotifier( const ClipboardEventNotifier& );
-  ClipboardEventNotifier& operator=( ClipboardEventNotifier& );
+  TextClipboardEventNotifier( const TextClipboardEventNotifier& );
+  TextClipboardEventNotifier& operator=( TextClipboardEventNotifier& );
 
 private:
 
   std::string mContent;    ///< The current selected content.
-  ClipboardEventSignalType mContentSelectedSignal;
+  TextClipboardEventSignalType mContentSelectedSignal;
 
-  static Dali::ClipboardEventNotifier mToolkitClipboardEventNotifier;
+  static Dali::TextClipboardEventNotifier mToolkitClipboardEventNotifier;
 
 public:
 
   // Helpers for public-api forwarding methods
 
-  inline static Internal::Adaptor::ClipboardEventNotifier& GetImplementation(Dali::ClipboardEventNotifier& detector)
+  inline static Internal::Adaptor::TextClipboardEventNotifier& GetImplementation(Dali::TextClipboardEventNotifier& detector)
   {
-    DALI_ASSERT_ALWAYS( detector && "ClipboardEventNotifier handle is empty" );
+    DALI_ASSERT_ALWAYS( detector && "TextClipboardEventNotifier handle is empty" );
 
     BaseObject& handle = detector.GetBaseObject();
 
-    return static_cast<Internal::Adaptor::ClipboardEventNotifier&>(handle);
+    return static_cast<Internal::Adaptor::TextClipboardEventNotifier&>(handle);
   }
 
-  inline static const Internal::Adaptor::ClipboardEventNotifier& GetImplementation(const Dali::ClipboardEventNotifier& detector)
+  inline static const Internal::Adaptor::TextClipboardEventNotifier& GetImplementation(const Dali::TextClipboardEventNotifier& detector)
   {
-    DALI_ASSERT_ALWAYS( detector && "ClipboardEventNotifier handle is empty" );
+    DALI_ASSERT_ALWAYS( detector && "TextClipboardEventNotifier handle is empty" );
 
     const BaseObject& handle = detector.GetBaseObject();
 
-    return static_cast<const Internal::Adaptor::ClipboardEventNotifier&>(handle);
+    return static_cast<const Internal::Adaptor::TextClipboardEventNotifier&>(handle);
   }
 
 };
 
-Dali::ClipboardEventNotifier ClipboardEventNotifier::mToolkitClipboardEventNotifier;
+Dali::TextClipboardEventNotifier TextClipboardEventNotifier::mToolkitClipboardEventNotifier;
 
-Dali::ClipboardEventNotifier ClipboardEventNotifier::New()
+Dali::TextClipboardEventNotifier TextClipboardEventNotifier::New()
 {
   return Get();
 }
 
-Dali::ClipboardEventNotifier ClipboardEventNotifier::Get()
+Dali::TextClipboardEventNotifier TextClipboardEventNotifier::Get()
 {
   if ( !mToolkitClipboardEventNotifier )
   {
-    mToolkitClipboardEventNotifier = Dali::ClipboardEventNotifier( new ClipboardEventNotifier );
+    mToolkitClipboardEventNotifier = Dali::TextClipboardEventNotifier( new TextClipboardEventNotifier );
   }
   return mToolkitClipboardEventNotifier;
 }
 
-const std::string& ClipboardEventNotifier::GetContent() const
+const std::string& TextClipboardEventNotifier::GetContent() const
 {
   return mContent;
 }
 
-void ClipboardEventNotifier::SetContent( const std::string& content )
+void TextClipboardEventNotifier::SetContent( const std::string& content )
 {
   mContent = content;
 }
 
-void ClipboardEventNotifier::ClearContent()
+void TextClipboardEventNotifier::ClearContent()
 {
   mContent.clear();
 }
 
-void ClipboardEventNotifier::EmitContentSelectedSignal()
+void TextClipboardEventNotifier::EmitContentSelectedSignal()
 {
   if ( !mContentSelectedSignal.Empty() )
   {
-    Dali::ClipboardEventNotifier handle( this );
+    Dali::TextClipboardEventNotifier handle( this );
     mContentSelectedSignal.Emit( handle );
   }
 }
 
-ClipboardEventNotifier::ClipboardEventNotifier()
+TextClipboardEventNotifier::TextClipboardEventNotifier()
 : mContent()
 {
 }
 
-ClipboardEventNotifier::~ClipboardEventNotifier()
+TextClipboardEventNotifier::~TextClipboardEventNotifier()
 {
 }
 
@@ -146,45 +146,45 @@ ClipboardEventNotifier::~ClipboardEventNotifier()
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-ClipboardEventNotifier::ClipboardEventNotifier()
+TextClipboardEventNotifier::TextClipboardEventNotifier()
 {
 }
 
-ClipboardEventNotifier ClipboardEventNotifier::Get()
+TextClipboardEventNotifier TextClipboardEventNotifier::Get()
 {
-  return Internal::Adaptor::ClipboardEventNotifier::Get();
+  return Internal::Adaptor::TextClipboardEventNotifier::Get();
 }
 
-ClipboardEventNotifier::~ClipboardEventNotifier()
+TextClipboardEventNotifier::~TextClipboardEventNotifier()
 {
 }
 
-const std::string& ClipboardEventNotifier::GetContent() const
+const std::string& TextClipboardEventNotifier::GetContent() const
 {
-  return Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).GetContent();
+  return Internal::Adaptor::TextClipboardEventNotifier::GetImplementation(*this).GetContent();
 }
 
-void ClipboardEventNotifier::SetContent( const std::string& content )
+void TextClipboardEventNotifier::SetContent( const std::string& content )
 {
-  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).SetContent(content);
+  Internal::Adaptor::TextClipboardEventNotifier::GetImplementation(*this).SetContent(content);
 }
 
-void ClipboardEventNotifier::ClearContent()
+void TextClipboardEventNotifier::ClearContent()
 {
-  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).ClearContent();
+  Internal::Adaptor::TextClipboardEventNotifier::GetImplementation(*this).ClearContent();
 }
 
-void ClipboardEventNotifier::EmitContentSelectedSignal()
+void TextClipboardEventNotifier::EmitContentSelectedSignal()
 {
-  Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).EmitContentSelectedSignal();
+  Internal::Adaptor::TextClipboardEventNotifier::GetImplementation(*this).EmitContentSelectedSignal();
 }
 
-ClipboardEventNotifier::ClipboardEventSignalType& ClipboardEventNotifier::ContentSelectedSignal()
+TextClipboardEventNotifier::TextClipboardEventSignalType& TextClipboardEventNotifier::ContentSelectedSignal()
 {
-  return Internal::Adaptor::ClipboardEventNotifier::GetImplementation(*this).ContentSelectedSignal();
+  return Internal::Adaptor::TextClipboardEventNotifier::GetImplementation(*this).ContentSelectedSignal();
 }
 
-ClipboardEventNotifier::ClipboardEventNotifier( Internal::Adaptor::ClipboardEventNotifier* notifier )
+TextClipboardEventNotifier::TextClipboardEventNotifier( Internal::Adaptor::TextClipboardEventNotifier* notifier )
 : BaseHandle( notifier )
 {
 }
index 282a0c0..b2aabe4 100644 (file)
@@ -22,7 +22,7 @@
 #include <string>
 
 // PUBLIC INCLUDES
-#define DALI_CLIPBOARD_EVENT_NOTIFIER_H
+#define DALI_TEXT_CLIPBOARD_EVENT_NOTIFIER_H
 #include <dali/public-api/object/base-handle.h>
 #include <dali/public-api/signals/dali-signal.h>
 
@@ -34,27 +34,27 @@ namespace Internal
 {
 namespace Adaptor
 {
-class ClipboardEventNotifier;
+class TextClipboardEventNotifier;
 }
 }
 
-class ClipboardEventNotifier : public BaseHandle
+class TextClipboardEventNotifier : public BaseHandle
 {
 public:
-  typedef Signal< void ( ClipboardEventNotifier& ) > ClipboardEventSignalType;
+  typedef Signal< void ( TextClipboardEventNotifier& ) > TextClipboardEventSignalType;
 
-  ClipboardEventNotifier();
-  static ClipboardEventNotifier Get();
-  ~ClipboardEventNotifier();
+  TextClipboardEventNotifier();
+  static TextClipboardEventNotifier Get();
+  ~TextClipboardEventNotifier();
 
   const std::string& GetContent() const;
   void SetContent( const std::string& content );
   void ClearContent();
 
   void EmitContentSelectedSignal();
-  ClipboardEventSignalType& ContentSelectedSignal();
+  TextClipboardEventSignalType& ContentSelectedSignal();
 
-  ClipboardEventNotifier( Internal::Adaptor::ClipboardEventNotifier* notifier );
+  TextClipboardEventNotifier( Internal::Adaptor::TextClipboardEventNotifier* notifier );
 };
 
 } // namespace Dali
index 15c74ae..177dc95 100644 (file)
@@ -19,7 +19,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-object.h>
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard-event-notifier.h>
 
 namespace Dali
 {
@@ -34,91 +34,91 @@ namespace Adaptor
  * Implementation of the Clip Board
  */
 
-class Clipboard :  public Dali::BaseObject
+class TextClipboard :  public Dali::BaseObject
 {
 public:
 
   /**
-   * @copydoc Dali::ClipboardEventNotifier::Get()
+   * @copydoc Dali::TextClipboardEventNotifier::Get()
    */
-  static Dali::Clipboard Get();
+  static Dali::TextClipboard Get();
 
   /**
    * Constructor
    * @param[in] ecoreXwin, The window is created by application.
    */
-  Clipboard(/*Ecore_X_Window ecoreXwin*/);
-  virtual ~Clipboard();
+  TextClipboard(/*Ecore_X_Window ecoreXwin*/);
+  virtual ~TextClipboard();
 
   /**
-   * @copydoc Dali::Clipboard::IsAvailable()
+   * @copydoc Dali::TextClipboard::IsAvailable()
    */
   static bool IsAvailable();
 
   /**
-   * @copydoc Dali::Clipboard::SetItem()
+   * @copydoc Dali::TextClipboard::SetItem()
    */
   bool SetItem(const std::string &itemData);
 
   /**
-   * @copydoc Dali::Clipboard::RequestItem()
+   * @copydoc Dali::TextClipboard::RequestItem()
    */
   void RequestItem();
 
   /**
-   * @copydoc Dali::Clipboard::NumberOfClipboardItems()
+   * @copydoc Dali::TextClipboard::NumberOfClipboardItems()
    */
   unsigned int NumberOfItems();
 
   /**
-   * @copydoc Dali::Clipboard::ShowClipboard()
+   * @copydoc Dali::TextClipboard::ShowClipboard()
    */
   void ShowClipboard();
 
   /**
-   * @copydoc Dali::Clipboard::HideClipboard()
+   * @copydoc Dali::TextClipboard::HideClipboard()
    */
   void HideClipboard();
 
   /**
-  * @copydoc Dali::Clipboard::IsVisible()
+  * @copydoc Dali::TextClipboard::IsVisible()
   */
   bool IsVisible() const;
 
 private:
-  Clipboard( const Clipboard& );
-  Clipboard& operator=( Clipboard& );
+  TextClipboard( const TextClipboard& );
+  TextClipboard& operator=( TextClipboard& );
 
-  static Dali::Clipboard mToolkitClipboard;
+  static Dali::TextClipboard mToolkitClipboard;
   bool mVisible;
   std::string mItem;
   int mCount;
-}; // class clipboard
+}; // class TextClipboard
 
 
-Dali::Clipboard Dali::Internal::Adaptor::Clipboard::mToolkitClipboard;
+Dali::TextClipboard Dali::Internal::Adaptor::TextClipboard::mToolkitClipboard;
 
 
-Clipboard::Clipboard()
+TextClipboard::TextClipboard()
 {
   mVisible = false;
   mCount = 0;
 }
 
-Clipboard::~Clipboard()
+TextClipboard::~TextClipboard()
 {
 }
 
-Dali::Clipboard Clipboard::Get()
+Dali::TextClipboard TextClipboard::Get()
 {
   if( ! mToolkitClipboard )
   {
-    mToolkitClipboard = Dali::Clipboard( new Dali::Internal::Adaptor::Clipboard() );
+    mToolkitClipboard = Dali::TextClipboard( new Dali::Internal::Adaptor::TextClipboard() );
   }
   return mToolkitClipboard;
 }
 
-bool Clipboard::IsAvailable()
+bool TextClipboard::IsAvailable()
 {
   if(mToolkitClipboard)
   {
@@ -127,16 +127,16 @@ bool Clipboard::IsAvailable()
   return false;
 }
 
-bool Clipboard::SetItem(const std::string &itemData )
+bool TextClipboard::SetItem(const std::string &itemData )
 {
   mItem = itemData;
   mCount = 1;
   return true;
 }
 
-void Clipboard::RequestItem()
+void TextClipboard::RequestItem()
 {
-  Dali::ClipboardEventNotifier clipboardEventNotifier(Dali::ClipboardEventNotifier::Get());
+  Dali::TextClipboardEventNotifier clipboardEventNotifier(Dali::TextClipboardEventNotifier::Get());
   if ( clipboardEventNotifier )
   {
     clipboardEventNotifier.SetContent( mItem );
@@ -144,22 +144,22 @@ void Clipboard::RequestItem()
   }
 }
 
-unsigned int Clipboard::NumberOfItems()
+unsigned int TextClipboard::NumberOfItems()
 {
   return mCount;
 }
 
-void Clipboard::ShowClipboard()
+void TextClipboard::ShowClipboard()
 {
   mVisible = true;
 }
 
-void Clipboard::HideClipboard()
+void TextClipboard::HideClipboard()
 {
   mVisible = false;
 }
 
-bool Clipboard::IsVisible() const
+bool TextClipboard::IsVisible() const
 {
   return mVisible;
 }
@@ -169,64 +169,64 @@ bool Clipboard::IsVisible() const
 } // namespace Internal
 
 
-inline static Internal::Adaptor::Clipboard& GetImplementation(Dali::Clipboard& clipboard)
+inline static Internal::Adaptor::TextClipboard& GetImplementation(Dali::TextClipboard& clipboard)
 {
   // Bypass any passed in clipboard handle - it probably won't be initialized
-  Dali::Clipboard theClipboard = Dali::Clipboard::Get();
+  Dali::TextClipboard theClipboard = Dali::TextClipboard::Get();
   BaseObject& object = theClipboard.GetBaseObject();
-  return static_cast<Internal::Adaptor::Clipboard&>(object);
+  return static_cast<Internal::Adaptor::TextClipboard&>(object);
 }
 
-inline static const  Internal::Adaptor::Clipboard& GetImplementation(const Dali::Clipboard& clipboard)
+inline static const  Internal::Adaptor::TextClipboard& GetImplementation(const Dali::TextClipboard& clipboard)
 {
   // Bypass any passed in clipboard handle - it probably won't be initialized
-  Dali::Clipboard theClipboard = Dali::Clipboard::Get();
+  Dali::TextClipboard theClipboard = Dali::TextClipboard::Get();
   const BaseObject& object = theClipboard.GetBaseObject();
-  return static_cast<const Internal::Adaptor::Clipboard&>(object);
+  return static_cast<const Internal::Adaptor::TextClipboard&>(object);
 }
 
 
-Clipboard::Clipboard()
+TextClipboard::TextClipboard()
 {
 }
-Clipboard::~Clipboard()
+TextClipboard::~TextClipboard()
 {
 }
-Clipboard::Clipboard(Internal::Adaptor::Clipboard *impl)
+TextClipboard::TextClipboard(Internal::Adaptor::TextClipboard *impl)
   : BaseHandle(impl)
 {
 }
 
-Clipboard Clipboard::Get()
+TextClipboard TextClipboard::Get()
 {
-  return Internal::Adaptor::Clipboard::Get();
+  return Internal::Adaptor::TextClipboard::Get();
 }
-bool Clipboard::SetItem( const std::string &itemData)
+bool TextClipboard::SetItem( const std::string &itemData)
 {
   return GetImplementation(*this).SetItem( itemData );
 }
 
-void Clipboard::RequestItem()
+void TextClipboard::RequestItem()
 {
   GetImplementation(*this).RequestItem();
 }
 
-unsigned int Clipboard::NumberOfItems()
+unsigned int TextClipboard::NumberOfItems()
 {
   return GetImplementation(*this).NumberOfItems();
 }
 
-void Clipboard::ShowClipboard()
+void TextClipboard::ShowClipboard()
 {
   GetImplementation(*this).ShowClipboard();
 }
 
-void Clipboard::HideClipboard()
+void TextClipboard::HideClipboard()
 {
   GetImplementation(*this).HideClipboard();
 }
 
-bool Clipboard::IsVisible() const
+bool TextClipboard::IsVisible() const
 {
   return GetImplementation(*this).IsVisible();
 }
index d3d684d..5757cff 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef  TOOLKIT_CLIPBOARD_H
-#define  TOOLKIT_CLIPBOARD_H
+#ifndef  TOOLKIT_TEXT_CLIPBOARD_H
+#define  TOOLKIT_TEXT_CLIPBOARD_H
 
 /*
  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
@@ -18,7 +18,7 @@
  *
  */
 
-#define DALI_CLIPBOARD_H
+#define DALI_TEXT_CLIPBOARD_H
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/rect.h>
@@ -32,7 +32,7 @@ namespace Internal DALI_INTERNAL
 
 namespace Adaptor
 {
-class Clipboard;
+class TextClipboard;
 }
 }
 
@@ -40,31 +40,31 @@ class Clipboard;
  * The Clipboard can operate using various funtion.
  * Clipboard can manage it's item and set show / hide status.
  */
-class Clipboard : public BaseHandle
+class TextClipboard : public BaseHandle
 {
 public:
   /**
    * Create an uninitialized Clipboard;
    *  this can be initialized with one of the derived Clipboard' New() methods
    */
-  Clipboard();
+  TextClipboard();
 
   /**
    * Non virtual destructor.
    */
-  ~Clipboard();
+  ~TextClipboard();
 
   /**
    * This constructor is used by Adaptor::GetClipboard().
    * @param[in] clipboard A pointer to the clipboard.
    */
-  Clipboard( Internal::Adaptor::Clipboard* clipboard );
+  TextClipboard( Internal::Adaptor::TextClipboard* clipboard );
 
   /**
-   * Retrieve a handle to the ClipboardEventNotifier instance
-   * @return A handle to the Clipboard
+   * Retrieve a handle to the TextClipboardEventNotifier instance
+   * @return A handle to the TextClipboard
    */
-  static Clipboard Get();
+  static TextClipboard Get();
 
   /**
    * @brief Checks whether the clipboard is available.
@@ -110,4 +110,4 @@ public:
 };
 } // namespace Dali
 
-#endif // TOOLKIT_CLIPBOARD_H
+#endif // TOOLKIT_TextCLIPBOARD_H
index 7ef0b0e..54ad18b 100644 (file)
  *
  */
 
-#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
+#include <dali-test-suite-utils.h>
 #include <dali-toolkit/public-api/particle-system/particle-domain.h>
+#include <dali-toolkit/public-api/particle-system/particle-emitter.h>
+#include <dali-toolkit/public-api/particle-system/particle-list.h>
 #include <dali-toolkit/public-api/particle-system/particle-modifier.h>
-#include <dali-toolkit/public-api/particle-system/particle-source.h>
 #include <dali-toolkit/public-api/particle-system/particle-renderer.h>
-#include <dali-toolkit/public-api/particle-system/particle-list.h>
+#include <dali-toolkit/public-api/particle-system/particle-source.h>
 #include <dali-toolkit/public-api/particle-system/particle.h>
-#include <dali-test-suite-utils.h>
 
 #include <dlfcn.h>
 
@@ -39,63 +39,57 @@ R InvokeNext(T* pObj, Args... args)
 {
   Dl_info info;
   dladdr(__builtin_return_address(0), &info);
-  using Func = R(*)(T*,Args...);
-  auto sym = (Func)(dlsym(RTLD_NEXT, info.dli_sname));
+  using Func = R (*)(T*, Args...);
+  auto sym   = (Func)(dlsym(RTLD_NEXT, info.dli_sname));
   return sym(pObj, args...);
 }
 
-// Create fake time getter
+static std::chrono::milliseconds currentTime(1u);
+static void                      AdvanceTimeByMs(uint32_t ms)
+{
+  currentTime += std::chrono::milliseconds(ms);
+}
+
 namespace Dali::Toolkit::ParticleSystem::Internal
 {
+// Create fake time getter
 struct ParticleEmitter
 {
   [[nodiscard]] std::chrono::milliseconds GetCurrentTimeMillis() const;
-
-  static std::chrono::milliseconds currentTime;
-
-  static void AdvanceTimeByMs( uint32_t ms)
-  {
-    currentTime += std::chrono::milliseconds(ms);
-  }
 };
-
-std::chrono::milliseconds ParticleEmitter::currentTime(1u);
-
 std::chrono::milliseconds ParticleEmitter::GetCurrentTimeMillis() const
 {
   [[maybe_unused]] auto value = InvokeNext<std::chrono::milliseconds>(this);
-   return std::chrono::milliseconds(currentTime);
-}
+  return std::chrono::milliseconds(currentTime);
 }
+} // namespace Dali::Toolkit::ParticleSystem::Internal
 
 using ParticleEmitterWrapper = Dali::Toolkit::ParticleSystem::Internal::ParticleEmitter;
 
 Texture CreateTexture()
 {
-  Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, 100, 100);
-  uint8_t* data = reinterpret_cast<uint8_t*>(malloc(100*100*4));
-  PixelData pixelData = PixelData::New(data, 100*100*4, 100, 100, Pixel::Format::RGBA8888, PixelData::FREE);
+  Texture   texture   = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, 100, 100);
+  uint8_t*  data      = reinterpret_cast<uint8_t*>(malloc(100 * 100 * 4));
+  PixelData pixelData = PixelData::New(data, 100 * 100 * 4, 100, 100, Pixel::Format::RGBA8888, PixelData::FREE);
   texture.Upload(pixelData);
   return texture;
 }
 
-
 /**
  * Test particle source
  */
 class TestSource : public ParticleSourceInterface
 {
 public:
-
   TestSource(ParticleEmitter* emitter)
+  : mEmitter(*emitter)
   {
-    mEmitter = *emitter;
   }
 
   void NewFrame()
   {
     mPromise = std::promise<uint32_t>();
-    mFuture = mPromise.get_future();
+    mFuture  = mPromise.get_future();
   }
 
   uint32_t Update(ParticleList& outList, uint32_t count) override
@@ -115,25 +109,24 @@ public:
     mInitialized = true;
   }
 
-  bool mInitialized{false};
-  std::future<uint32_t> mFuture;
+  bool                   mInitialized{false};
+  std::future<uint32_t>  mFuture;
   std::promise<uint32_t> mPromise;
-  ParticleEmitter mEmitter;
+  ParticleEmitter&       mEmitter;
 };
 
 class TestSource2 : public ParticleSourceInterface
 {
 public:
-
   TestSource2(ParticleEmitter* emitter)
+  : mEmitter(*emitter)
   {
-    mEmitter = *emitter;
   }
 
   void NewFrame()
   {
     mPromise = std::promise<uint32_t>();
-    mFuture = mPromise.get_future();
+    mFuture  = mPromise.get_future();
   }
 
   uint32_t Update(ParticleList& outList, uint32_t count) override
@@ -151,9 +144,9 @@ public:
       [[maybe_unused]] auto& pos = particle.GetByIndex<Vector3>(mStreamBasePos);
 
       [[maybe_unused]] auto& gpos = particle.Get<Vector3>(ParticleStream::POSITION_STREAM_BIT);
-      [[maybe_unused]] auto& col = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
-      [[maybe_unused]] auto& vel = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
-      [[maybe_unused]] auto& sca = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
+      [[maybe_unused]] auto& col  = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
+      [[maybe_unused]] auto& vel  = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
+      [[maybe_unused]] auto& sca  = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
       //auto& basePos = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
     }
 
@@ -164,15 +157,14 @@ public:
   {
     // calls initialized
     mStreamBasePos = mEmitter.GetParticleList().AddLocalStream<Vector3>(Vector3::ZERO);
-    mInitialized = true;
+    mInitialized   = true;
   }
 
-  bool mInitialized{false};
-  std::future<uint32_t> mFuture;
+  bool                   mInitialized{false};
+  std::future<uint32_t>  mFuture;
   std::promise<uint32_t> mPromise;
-  uint32_t mStreamBasePos{0u};
-  ParticleEmitter mEmitter;
-
+  uint32_t               mStreamBasePos{0u};
+  ParticleEmitter&       mEmitter;
 };
 /**
  * Sample of FlameModifier
@@ -181,7 +173,6 @@ struct TestModifier : public ParticleModifierInterface
 {
   void Update(ParticleList& particleList, uint32_t firstParticleIndex, uint32_t particleCount) override
   {
-
   }
 };
 
@@ -189,7 +180,6 @@ struct TestModifierMT : public ParticleModifierInterface
 {
   void Update(ParticleList& particleList, uint32_t firstParticleIndex, uint32_t particleCount) override
   {
-
   }
 
   bool IsMultiThreaded() override
@@ -205,16 +195,15 @@ struct TestModifier2 : public ParticleModifierInterface
 {
   void Update(ParticleList& particleList, uint32_t firstParticleIndex, uint32_t particleCount) override
   {
-
   }
 };
 
 struct EmitterGroup
 {
-  ParticleEmitter emitter;
+  ParticleEmitter  emitter;
   ParticleRenderer renderer;
   ParticleModifier modifier;
-  ParticleSource source;
+  ParticleSource   source;
 };
 
 // Helper function to create emitter (every test will be doing that)
@@ -224,7 +213,7 @@ ParticleEmitter CreateEmitter(EmitterGroup* output = nullptr)
   auto emitter = ParticleEmitter::New();
 
   bool result = (emitter != nullptr);
-  DALI_TEST_EQUALS( result, true, TEST_LOCATION );
+  DALI_TEST_EQUALS(result, true, TEST_LOCATION);
 
   // Create test source
   auto source = ParticleSource::New<SOURCE>(&emitter);
@@ -268,23 +257,23 @@ ParticleEmitter CreateEmitter(EmitterGroup* output = nullptr)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::INCOMPLETE, TEST_LOCATION);
 
   // Attach all components to the emitter
-  emitter.SetSource( source );
-  emitter.SetRenderer( renderer );
-  emitter.AddModifier( modifier );
-  emitter.SetDomain( domain );
+  emitter.SetSource(source);
+  emitter.SetRenderer(renderer);
+  emitter.AddModifier(modifier);
+  emitter.SetDomain(domain);
 
-  auto domain0 = emitter.GetDomain();
+  auto domain0   = emitter.GetDomain();
   auto renderer0 = emitter.GetRenderer();
 
-  DALI_TEST_EQUALS( renderer0, renderer, TEST_LOCATION);
-  DALI_TEST_EQUALS( domain0, domain, TEST_LOCATION);
+  DALI_TEST_EQUALS(renderer0, renderer, TEST_LOCATION);
+  DALI_TEST_EQUALS(domain0, domain, TEST_LOCATION);
 
   if(output)
   {
-    output->emitter = emitter;
+    output->emitter  = emitter;
     output->renderer = renderer;
     output->modifier = modifier;
-    output->source = source;
+    output->source   = source;
   }
 
   return emitter;
@@ -296,7 +285,7 @@ int UtcDaliParticleSystemEmitterNew(void)
   auto emitter = ParticleEmitter::New();
 
   bool result = (emitter != nullptr);
-  DALI_TEST_EQUALS( result, true, TEST_LOCATION );
+  DALI_TEST_EQUALS(result, true, TEST_LOCATION);
 
   // Create test source
   auto source = ParticleSource::New<TestSource>(&emitter);
@@ -317,10 +306,10 @@ int UtcDaliParticleSystemEmitterNew(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::INCOMPLETE, TEST_LOCATION);
 
   // Attach all components to the emitter
-  emitter.SetSource( source );
-  emitter.SetRenderer( renderer );
-  emitter.AddModifier( modifier );
-  emitter.SetDomain( domain );
+  emitter.SetSource(source);
+  emitter.SetRenderer(renderer);
+  emitter.AddModifier(modifier);
+  emitter.SetDomain(domain);
 
   // test status again (domain is optional);
   ready = emitter.GetStatus();
@@ -337,7 +326,7 @@ int UtcDaliParticleSystemEmitterModifierStack(void)
   auto emitter = ParticleEmitter::New();
 
   bool result = (emitter != nullptr);
-  DALI_TEST_EQUALS( result, true, TEST_LOCATION );
+  DALI_TEST_EQUALS(result, true, TEST_LOCATION);
 
   // Create test source
   auto source = ParticleSource::New<TestSource>(&emitter);
@@ -360,13 +349,13 @@ int UtcDaliParticleSystemEmitterModifierStack(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::INCOMPLETE, TEST_LOCATION);
 
   // Attach all components to the emitter
-  emitter.SetSource( source );
-  emitter.SetRenderer( renderer );
-  emitter.AddModifier( modifier0 );
-  emitter.AddModifier( modifier1 );
-  emitter.AddModifier( modifier2 );
+  emitter.SetSource(source);
+  emitter.SetRenderer(renderer);
+  emitter.AddModifier(modifier0);
+  emitter.AddModifier(modifier1);
+  emitter.AddModifier(modifier2);
 
-  emitter.SetDomain( domain );
+  emitter.SetDomain(domain);
 
   // test status again (domain is optional);
   ready = emitter.GetStatus();
@@ -402,8 +391,8 @@ int UtcDaliParticleSystemTest(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
 
   // Set initial parameters of system
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 5000 );
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
 
   // Test getters
   auto initialParticleCount = emitter.GetInitialParticleCount();
@@ -434,19 +423,19 @@ int UtcDaliParticleSystemTest(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -470,8 +459,8 @@ int UtcDaliParticleSystemTestWithTextureScreen(void)
 
   // Blending mode with screen
   auto texture = CreateTexture();
-  group.renderer.SetTexture( texture );
-  group.renderer.SetBlendingMode( BlendingMode::SCREEN );
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::SCREEN);
 
   // test status again (domain is optional);
   auto ready = emitter.GetStatus();
@@ -480,8 +469,8 @@ int UtcDaliParticleSystemTestWithTextureScreen(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
 
   // Set initial parameters of system
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 5000 );
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
 
   // Test getters
   auto initialParticleCount = emitter.GetInitialParticleCount();
@@ -512,19 +501,19 @@ int UtcDaliParticleSystemTestWithTextureScreen(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -548,8 +537,8 @@ int UtcDaliParticleSystemTestWithTextureAdd(void)
 
   // Blending mode with screen
   auto texture = CreateTexture();
-  group.renderer.SetTexture( texture );
-  group.renderer.SetBlendingMode( BlendingMode::DEFAULT );
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::DEFAULT);
 
   // test status again (domain is optional);
   auto ready = emitter.GetStatus();
@@ -558,8 +547,8 @@ int UtcDaliParticleSystemTestWithTextureAdd(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
 
   // Set initial parameters of system
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 5000 );
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
 
   // Test getters
   auto initialParticleCount = emitter.GetInitialParticleCount();
@@ -590,19 +579,19 @@ int UtcDaliParticleSystemTestWithTextureAdd(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -624,22 +613,22 @@ int UtcDaliParticleSystemTestInitialSetup(void)
 
   auto emitter = CreateEmitter<TestSource, TestModifier>(&group);
 
-  emitter.SetEmissionRate( 1000 );
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 10000 );
+  emitter.SetEmissionRate(1000);
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(10000);
 
   auto emissionRate = emitter.GetEmissionRate();
   auto initialCount = emitter.GetInitialParticleCount();
-  auto activeCount = emitter.GetActiveParticlesLimit();
+  auto activeCount  = emitter.GetActiveParticlesLimit();
 
-  DALI_TEST_EQUALS( emissionRate, 1000, TEST_LOCATION);
-  DALI_TEST_EQUALS( initialCount, 1000, TEST_LOCATION);
-  DALI_TEST_EQUALS( activeCount, 10000, TEST_LOCATION);
+  DALI_TEST_EQUALS(emissionRate, 1000, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialCount, 1000, TEST_LOCATION);
+  DALI_TEST_EQUALS(activeCount, 10000, TEST_LOCATION);
 
   // Blending mode with screen
   auto texture = CreateTexture();
-  group.renderer.SetTexture( texture );
-  group.renderer.SetBlendingMode( BlendingMode::DEFAULT );
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::DEFAULT);
 
   // test status again (domain is optional);
   auto ready = emitter.GetStatus();
@@ -648,8 +637,8 @@ int UtcDaliParticleSystemTestInitialSetup(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
 
   // Set initial parameters of system
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 5000 );
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
 
   // Test getters
   auto initialParticleCount = emitter.GetInitialParticleCount();
@@ -680,19 +669,19 @@ int UtcDaliParticleSystemTestInitialSetup(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -714,18 +703,18 @@ int UtcDaliParticleSystemTestMT(void)
 
   auto emitter = CreateEmitter<TestSource, TestModifierMT>(&group);
 
-  emitter.SetEmissionRate( 10000 );
-  emitter.SetInitialParticleCount( 10000 );
-  emitter.SetActiveParticlesLimit( 20000 );
-  emitter.SetParticleCount( 300000 );
+  emitter.SetEmissionRate(10000);
+  emitter.SetInitialParticleCount(10000);
+  emitter.SetActiveParticlesLimit(20000);
+  emitter.SetParticleCount(300000);
 
   auto emissionRate = emitter.GetEmissionRate();
   auto initialCount = emitter.GetInitialParticleCount();
-  auto activeCount = emitter.GetActiveParticlesLimit();
+  auto activeCount  = emitter.GetActiveParticlesLimit();
 
-  DALI_TEST_EQUALS( emissionRate, 10000, TEST_LOCATION);
-  DALI_TEST_EQUALS( initialCount, 10000, TEST_LOCATION);
-  DALI_TEST_EQUALS( activeCount, 20000, TEST_LOCATION);
+  DALI_TEST_EQUALS(emissionRate, 10000, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialCount, 10000, TEST_LOCATION);
+  DALI_TEST_EQUALS(activeCount, 20000, TEST_LOCATION);
 
   emitter.EnableParallelProcessing(true);
 
@@ -734,9 +723,9 @@ int UtcDaliParticleSystemTestMT(void)
 
   // Blending mode with screen
   auto texture = CreateTexture();
-  group.renderer.SetTexture( texture );
-  group.renderer.SetBlendingMode( BlendingMode::DEFAULT );
-  
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::DEFAULT);
+
   // test status again (domain is optional);
   auto ready = emitter.GetStatus();
 
@@ -765,19 +754,19 @@ int UtcDaliParticleSystemTestMT(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -799,24 +788,24 @@ int UtcDaliParticleSystemTestParticleSource(void)
 
   auto emitter = CreateEmitter<TestSource2, TestModifier>(&group);
 
-  emitter.SetEmissionRate( 1000 );
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 10000 );
+  emitter.SetEmissionRate(1000);
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(10000);
 
   auto emissionRate = emitter.GetEmissionRate();
   auto initialCount = emitter.GetInitialParticleCount();
-  auto activeCount = emitter.GetActiveParticlesLimit();
+  auto activeCount  = emitter.GetActiveParticlesLimit();
 
-  DALI_TEST_EQUALS( emissionRate, 1000, TEST_LOCATION);
-  DALI_TEST_EQUALS( initialCount, 1000, TEST_LOCATION);
-  DALI_TEST_EQUALS( activeCount, 10000, TEST_LOCATION);
+  DALI_TEST_EQUALS(emissionRate, 1000, TEST_LOCATION);
+  DALI_TEST_EQUALS(initialCount, 1000, TEST_LOCATION);
+  DALI_TEST_EQUALS(activeCount, 10000, TEST_LOCATION);
 
   emitter.EnableParallelProcessing(true);
 
   // Blending mode with screen
   auto texture = CreateTexture();
-  group.renderer.SetTexture( texture );
-  group.renderer.SetBlendingMode( BlendingMode::DEFAULT );
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::DEFAULT);
 
   // test status again (domain is optional);
   auto ready = emitter.GetStatus();
@@ -825,8 +814,8 @@ int UtcDaliParticleSystemTestParticleSource(void)
   DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
 
   // Set initial parameters of system
-  emitter.SetInitialParticleCount( 1000 );
-  emitter.SetActiveParticlesLimit( 5000 );
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
 
   // Test getters
   auto initialParticleCount = emitter.GetInitialParticleCount();
@@ -857,19 +846,19 @@ int UtcDaliParticleSystemTestParticleSource(void)
 
   // Run 3 more frames advancing by 1000ms which should
   // emit particles based on emission rate
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
   application.Render();
 
-  ParticleEmitterWrapper::AdvanceTimeByMs(1000);
+  AdvanceTimeByMs(1000);
 
   sourceCallback.NewFrame();
   application.SendNotification();
@@ -883,4 +872,91 @@ int UtcDaliParticleSystemTestParticleSource(void)
   application.Render();
 
   END_TEST;
+}
+
+int UtcDaliParticleSystemReplaceEmitter(void)
+{
+  TestApplication application;
+
+  // Create actor to be used with emitter
+  Actor actor = Actor::New();
+  application.GetScene().Add(actor);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100, 100));
+
+  EmitterGroup group;
+
+  auto emitter = CreateEmitter<TestSource, TestModifier>(&group);
+
+  // Blending mode with screen
+  auto texture = CreateTexture();
+  group.renderer.SetTexture(texture);
+  group.renderer.SetBlendingMode(BlendingMode::DEFAULT);
+
+  // test status again (domain is optional);
+  auto ready = emitter.GetStatus();
+
+  // Emitter should return status incomplete
+  DALI_TEST_EQUALS(ready, ParticleEmitter::Status::READY, TEST_LOCATION);
+
+  // Set initial parameters of system
+  emitter.SetInitialParticleCount(1000);
+  emitter.SetActiveParticlesLimit(5000);
+
+  // Test getters
+  auto initialParticleCount = emitter.GetInitialParticleCount();
+  auto activeParticlesLimit = emitter.GetActiveParticlesLimit();
+
+  DALI_TEST_EQUALS(initialParticleCount, 1000, TEST_LOCATION);
+  DALI_TEST_EQUALS(activeParticlesLimit, 5000, TEST_LOCATION);
+
+  // Attach emitter to actor
+  emitter.AttachTo(actor);
+
+  // Start emitter
+  emitter.Start();
+
+  auto status = emitter.GetStatus();
+  DALI_TEST_EQUALS(status, ParticleEmitter::Status::STARTED, TEST_LOCATION);
+
+  auto& sourceCallback = dynamic_cast<TestSource&>(emitter.GetSource().GetSourceCallback());
+
+  // Run simulation
+  sourceCallback.NewFrame();
+  application.SendNotification();
+  application.Render();
+
+  // First call into source callback should emit initial number of particles
+  auto emittedParticleCount = sourceCallback.mFuture.get();
+  DALI_TEST_EQUALS(emittedParticleCount, 1000, TEST_LOCATION);
+
+  // Run 3 more frames advancing by 1000ms which should
+  // emit particles based on emission rate
+  AdvanceTimeByMs(1000);
+
+  sourceCallback.NewFrame();
+  application.SendNotification();
+  application.Render();
+
+  AdvanceTimeByMs(1000);
+
+  sourceCallback.NewFrame();
+  application.SendNotification();
+  application.Render();
+
+  AdvanceTimeByMs(1000);
+
+  sourceCallback.NewFrame();
+  application.SendNotification();
+  application.Render();
+
+  // replace emitter
+  auto                  oldEmitter = emitter.GetObjectPtr(); // store old emitter
+  [[maybe_unused]] auto i          = oldEmitter->ReferenceCount();
+  // Reset group
+  group = {};
+
+  emitter = CreateEmitter<TestSource, TestModifier>(&group);
+  DALI_TEST_EQUALS(bool(emitter.GetObjectPtr() != oldEmitter), true, TEST_LOCATION);
+
+  END_TEST;
 }
\ No newline at end of file
index 17d7d30..389143b 100644 (file)
@@ -23,7 +23,7 @@
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
 
 #include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/adaptor-framework/clipboard.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard.h>
 #include <dali/devel-api/adaptor-framework/key-devel.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <dali/devel-api/events/pan-gesture-devel.h>
@@ -2166,7 +2166,7 @@ int utcDaliTextEditorEvent03(void)
   application.Render();
 
   // Send some taps and check text controller with clipboard window
-  Dali::Clipboard clipboard = Clipboard::Get();
+  Dali::TextClipboard clipboard = TextClipboard::Get();
   clipboard.ShowClipboard();
   TestGenerateTap(application, 3.0f, 25.0f, 100);
   clipboard.HideClipboard();
index d6ac646..357e456 100644 (file)
@@ -2981,7 +2981,7 @@ int utcDaliTextFieldEvent08(void)
   ToolkitTestApplication application;
   tet_infoline(" utcDaliTextFieldEvent08");
 
-  Dali::Clipboard clipboard = Clipboard::Get();
+  Dali::TextClipboard clipboard = TextClipboard::Get();
   clipboard.SetItem("testTextFieldEvent");
 
   // Checks Longpress when only place holder text
index 9c599c5..5746b93 100644 (file)
@@ -835,6 +835,14 @@ void SceneView::UpdateSkybox(const std::string& skyboxUrl, Scene3D::EnvironmentM
       Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask);
       mSkyboxLoadTask.Reset();
     }
+
+    if(mSkybox)
+    {
+        mSkybox.Unparent();
+        mSkybox.Reset();
+        mSkyboxTexture.Reset();
+    }
+
     mSkyboxDirty         = false;
     mSkyboxResourceReady = true;
   }
index d57d974..8be7c88 100644 (file)
@@ -4,6 +4,8 @@
 // https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-vert.glsl
 // Commit dc84b5e374fb3d23153d2248a338ef88173f9eb6
 
+#define MORPH defined(MORPH_POSITION) || defined(MORPH_NORMAL) || defined(MORPH_TANGENT)
+
 #ifdef HIGHP
   precision highp float;
 #else
index a117d48..4ce7d57 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-scene3d/public-api/loader/node-definition.h>
 #include <dali-scene3d/public-api/loader/renderer-state.h>
 #include <dali-scene3d/public-api/loader/utils.h>
+#include <dali-scene3d/public-api/loader/shader-definition-option.h>
 
 namespace Dali
 {
@@ -100,13 +101,13 @@ Material::Material()
   mTextureInformations[SPECULAR].mSemantic       = Scene3D::Loader::MaterialDefinition::SPECULAR;
   mTextureInformations[SPECULAR_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR_COLOR;
 
-  mTextureInformations[BASE_COLOR].mDefineKeyword         = "BASECOLOR_TEX";
-  mTextureInformations[METALLIC_ROUGHNESS].mDefineKeyword = "METALLIC_ROUGHNESS_TEX";
-  mTextureInformations[NORMAL].mDefineKeyword             = "NORMAL_TEX";
-  mTextureInformations[OCCLUSION].mDefineKeyword          = "OCCLUSION";
-  mTextureInformations[EMISSIVE].mDefineKeyword           = "EMISSIVE";
-  mTextureInformations[SPECULAR].mDefineKeyword           = "MATERIAL_SPECULAR_TEXTURE";
-  mTextureInformations[SPECULAR_COLOR].mDefineKeyword     = "MATERIAL_SPECULAR_COLOR_TEXTURE";
+  mTextureInformations[BASE_COLOR].mDefineKeyword         = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE).data();
+  mTextureInformations[METALLIC_ROUGHNESS].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE).data();
+  mTextureInformations[NORMAL].mDefineKeyword             = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE).data();
+  mTextureInformations[OCCLUSION].mDefineKeyword          = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::OCCLUSION).data();
+  mTextureInformations[EMISSIVE].mDefineKeyword           = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::EMISSIVE).data();
+  mTextureInformations[SPECULAR].mDefineKeyword           = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::SPECULAR).data();
+  mTextureInformations[SPECULAR_COLOR].mDefineKeyword     = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR).data();
 
   mTextureInformations[TextureIndex::EMISSIVE].mFactor = Vector4::ZERO;
 }
index 569be53..df71d6d 100644 (file)
@@ -49,7 +49,6 @@ BaseHandle Create()
 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelPrimitive, Dali::BaseHandle, Create);
 DALI_TYPE_REGISTRATION_END()
 
-constexpr std::string_view MORPH_KEYWORD             = "MORPH";
 constexpr std::string_view MORPH_POSITION_KEYWORD    = "MORPH_POSITION";
 constexpr std::string_view MORPH_NORMAL_KEYWORD      = "MORPH_NORMAL";
 constexpr std::string_view MORPH_TANGENT_KEYWORD     = "MORPH_TANGENT";
@@ -284,7 +283,6 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
       {
         defines.push_back(MORPH_TANGENT_KEYWORD.data());
       }
-      defines.push_back(MORPH_KEYWORD.data());
       if(mBlendShapeData.version == Scene3D::Loader::BlendShapes::Version::VERSION_2_0)
       {
         defines.push_back(MORPH_VERSION_2_0_KEYWORD.data());
index f039518..43e992f 100644 (file)
@@ -33,6 +33,7 @@ set(scene3d_src_files ${scene3d_src_files}
        ${scene3d_public_api_dir}/loader/scene-definition.cpp
        ${scene3d_public_api_dir}/loader/shader-definition.cpp
        ${scene3d_public_api_dir}/loader/shader-definition-factory.cpp
+       ${scene3d_public_api_dir}/loader/shader-definition-option.cpp
        ${scene3d_public_api_dir}/loader/skinning-details.cpp
        ${scene3d_public_api_dir}/loader/string-callback.cpp
        ${scene3d_public_api_dir}/loader/utils.cpp
index 0d1e346..5eadd67 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali-scene3d/internal/loader/hash.h>
 #include <dali-scene3d/public-api/loader/blend-shape-details.h>
 #include <dali-scene3d/public-api/loader/node-definition.h>
+#include <dali-scene3d/public-api/loader/shader-definition-option.h>
 
 namespace Dali::Scene3D::Loader
 {
@@ -60,90 +61,92 @@ struct ResourceReceiver : IResourceReceiver
   }
 };
 
-uint64_t HashNode(const MaterialDefinition& materialDef, const MeshDefinition& meshDef)
+ShaderDefinitionOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinition& meshDef)
 {
-  Hash hash;
+  ShaderDefinitionOption option;
 
   const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY);
-  hash.Add(hasTransparency);
+  if(hasTransparency)
+  {
+    option.SetTransparency();
+  }
 
   if(hasTransparency ||
-     materialDef.CheckTextures(MaterialDefinition::ALBEDO) ||
-     materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS) ||
-     materialDef.CheckTextures(MaterialDefinition::NORMAL))
+     !materialDef.CheckTextures(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC) ||
+     !materialDef.CheckTextures(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS))
   {
-    hash.Add("3TEX");
+    option.AddOption(ShaderDefinitionOption::Type::THREE_TEXTURE);
 
     // For the glTF, each of basecolor, metallic_roughness, normal texture is not essential.
-    if(materialDef.CheckTextures(MaterialDefinition::ALBEDO))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO))
     {
-      hash.Add("BCTEX");
+      option.AddOption(ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE);
     }
 
     if(materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS))
     {
-      hash.Add("MRTEX");
+      option.AddOption(ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE);
     }
 
-    if(materialDef.CheckTextures(MaterialDefinition::NORMAL))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::NORMAL))
     {
-      hash.Add("NTEX");
+      option.AddOption(ShaderDefinitionOption::Type::NORMAL_TEXTURE);
     }
   }
 
   if(materialDef.GetAlphaCutoff() > 0.f)
   {
-    hash.Add("ALPH" /*A_TEST*/);
+    option.AddOption(ShaderDefinitionOption::Type::ALPHA_TEST);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE))
   {
-    hash.Add("SSS");
+    option.AddOption(ShaderDefinitionOption::Type::SUBSURFACE);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
   {
-    hash.Add("OCCL" /*USION*/);
+    option.AddOption(ShaderDefinitionOption::Type::OCCLUSION);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
   {
-    hash.Add("EMIS" /*SIVE*/);
+    option.AddOption(ShaderDefinitionOption::Type::EMISSIVE);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
   {
-    hash.Add("SPECTEX");
+    option.AddOption(ShaderDefinitionOption::Type::SPECULAR);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
   {
-    hash.Add("SPECCOLTEX");
+    option.AddOption(ShaderDefinitionOption::Type::SPECULAR_COLOR);
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
-    hash.Add("GLTF" /*_CHANNELS*/);
+    option.AddOption(ShaderDefinitionOption::Type::GLTF_CHANNELS);
   }
 
   if(meshDef.IsSkinned())
   {
-    hash.Add("SKIN" /*NING*/);
+    option.AddOption(ShaderDefinitionOption::Type::SKINNING);
   }
 
   if(MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL))
   {
-    hash.Add("FLIP" /*_V*/);
+    option.AddOption(ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL);
   }
 
   if(meshDef.mColors.IsDefined())
   {
-    hash.Add("COLATT");
+    option.AddOption(ShaderDefinitionOption::Type::COLOR_ATTRIBUTE);
   }
 
   if(meshDef.mTangentType == Property::VECTOR4)
   {
-    hash.Add("V4TAN");
+    option.AddOption(ShaderDefinitionOption::Type::VEC4_TANGENT);
   }
 
   if(meshDef.HasBlendShapes())
@@ -154,31 +157,29 @@ uint64_t HashNode(const MaterialDefinition& materialDef, const MeshDefinition& m
     meshDef.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents);
     if(hasPositions)
     {
-      hash.Add("MORPHPOS");
+      option.AddOption(ShaderDefinitionOption::Type::MORPH_POSITION);
     }
 
     if(hasNormals)
     {
-      hash.Add("MORPHNOR");
+      option.AddOption(ShaderDefinitionOption::Type::MORPH_NORMAL);
     }
 
     if(hasTangents)
     {
-      hash.Add("MORPHTAN");
+      option.AddOption(ShaderDefinitionOption::Type::MORPH_TANGENT);
     }
 
     if(hasPositions || hasNormals || hasTangents)
     {
-      hash.Add("MORPH");
-
       if(BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion)
       {
-        hash.Add("MORPHV2");
+        option.AddOption(ShaderDefinitionOption::Type::MORPH_VERSION_2_0);
       }
     }
   }
 
-  return hash;
+  return option;
 }
 } // namespace
 
@@ -214,9 +215,10 @@ Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& rendera
     return INVALID_INDEX;
   }
 
-  auto&    shaderMap = mImpl->mShaderMap;
-  uint64_t hash      = HashNode(*receiver.mMaterialDef, *receiver.mMeshDef);
-  auto     iFind     = shaderMap.find(hash);
+  auto&                  shaderMap = mImpl->mShaderMap;
+  ShaderDefinitionOption option    = MakeOption(*receiver.mMaterialDef, *receiver.mMeshDef);
+  uint64_t               hash      = option.GetOptionHash();
+  auto                   iFind     = shaderMap.find(hash);
   if(iFind != shaderMap.end())
   {
     renderable.mShaderIdx = iFind->second;
@@ -240,119 +242,7 @@ Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& rendera
       shaderDef.mRendererState = (shaderDef.mRendererState | RendererState::ALPHA_BLEND);
     }
 
-    if(hasTransparency ||
-       !materialDef.CheckTextures(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC) ||
-       !materialDef.CheckTextures(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS))
-
-    {
-      shaderDef.mDefines.push_back("THREE_TEX");
-
-      // For the glTF, each of basecolor, metallic_roughness, normal texture is not essential.
-      if(MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO))
-      {
-        shaderDef.mDefines.push_back("BASECOLOR_TEX");
-      }
-
-      if(materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS))
-      {
-        shaderDef.mDefines.push_back("METALLIC_ROUGHNESS_TEX");
-      }
-
-      if(MaskMatch(materialDef.mFlags, MaterialDefinition::NORMAL))
-      {
-        shaderDef.mDefines.push_back("NORMAL_TEX");
-      }
-    }
-
-    if(materialDef.GetAlphaCutoff() > 0.f)
-    {
-      shaderDef.mDefines.push_back("ALPHA_TEST");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE))
-    {
-      shaderDef.mDefines.push_back("SSS");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
-    {
-      shaderDef.mDefines.push_back("OCCLUSION");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
-    {
-      shaderDef.mDefines.push_back("EMISSIVE_TEXTURE");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
-    {
-      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_TEXTURE");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
-    {
-      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_COLOR_TEXTURE");
-    }
-
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
-    {
-      shaderDef.mDefines.push_back("GLTF_CHANNELS");
-    }
-
-    const auto& meshDef = *receiver.mMeshDef;
-    if(meshDef.IsSkinned())
-    {
-      shaderDef.mDefines.push_back("SKINNING");
-    }
-
-    if(MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL))
-    {
-      shaderDef.mDefines.push_back("FLIP_V");
-    }
-
-    if(meshDef.mColors.IsDefined())
-    {
-      shaderDef.mDefines.push_back("COLOR_ATTRIBUTE");
-    }
-
-    if(meshDef.mTangentType == Property::VECTOR4)
-    {
-      shaderDef.mDefines.push_back("VEC4_TANGENT");
-    }
-
-    if(meshDef.HasBlendShapes())
-    {
-      bool hasPositions = false;
-      bool hasNormals   = false;
-      bool hasTangents  = false;
-      meshDef.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents);
-
-      if(hasPositions)
-      {
-        shaderDef.mDefines.push_back("MORPH_POSITION");
-      }
-
-      if(hasNormals)
-      {
-        shaderDef.mDefines.push_back("MORPH_NORMAL");
-      }
-
-      if(hasTangents)
-      {
-        shaderDef.mDefines.push_back("MORPH_TANGENT");
-      }
-
-      if(hasPositions || hasNormals || hasTangents)
-      {
-        shaderDef.mDefines.push_back("MORPH");
-
-        if(BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion)
-        {
-          shaderDef.mDefines.push_back("MORPH_VERSION_2_0");
-        }
-      }
-    }
-
+    option.GetDefines(shaderDef.mDefines);
     shaderDef.mUniforms["uCubeMatrix"] = Matrix::IDENTITY;
 
     Index result    = resources.mShaders.size();
diff --git a/dali-scene3d/public-api/loader/shader-definition-option.cpp b/dali-scene3d/public-api/loader/shader-definition-option.cpp
new file mode 100644 (file)
index 0000000..18360de
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/shader-definition-option.h>
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali::Scene3D::Loader
+{
+namespace
+{
+static constexpr std::string_view OPTION_KEYWORD[] =
+  {
+    "GLTF_CHANNELS",
+    "THREE_TEX",
+    "BASECOLOR_TEX",
+    "METALLIC_ROUGHNESS_TEX",
+    "NORMAL_TEX",
+    "OCCLUSION",
+    "EMISSIVE_TEXTURE",
+    "ALPHA_TEST",
+    "SSS",
+    "MATERIAL_SPECULAR_TEXTURE",
+    "MATERIAL_SPECULAR_COLOR_TEXTURE",
+    "SKINNING",
+    "FLIP_V",
+    "COLOR_ATTRIBUTE",
+    "VEC4_TANGENT",
+    "MORPH_POSITION",
+    "MORPH_NORMAL",
+    "MORPH_TANGENT",
+    "MORPH_VERSION_2_0",
+};
+static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
+} // namespace
+
+void ShaderDefinitionOption::SetTransparency()
+{
+  mOptionHash |= (1 << NUMBER_OF_OPTIONS);
+}
+
+void ShaderDefinitionOption::AddOption(Type shaderDefinitionOptionType)
+{
+  mOptionHash |= (1 << static_cast<uint32_t>(shaderDefinitionOptionType));
+}
+
+uint64_t ShaderDefinitionOption::GetOptionHash() const
+{
+  return mOptionHash;
+}
+
+void ShaderDefinitionOption::GetDefines(std::vector<std::string>& defines) const
+{
+  defines.clear();
+  for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i)
+  {
+    if(mOptionHash & 1 << i)
+    {
+      defines.push_back(OPTION_KEYWORD[i].data());
+    }
+  }
+}
+
+std::string_view ShaderDefinitionOption::GetDefineKeyword(Type shaderDefinitionOptionType)
+{
+  return OPTION_KEYWORD[static_cast<uint32_t>(shaderDefinitionOptionType)];
+}
+
+} // namespace Dali::Scene3D::Loader
diff --git a/dali-scene3d/public-api/loader/shader-definition-option.h b/dali-scene3d/public-api/loader/shader-definition-option.h
new file mode 100644 (file)
index 0000000..3dc56be
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_
+#define DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDER
+#include <dali/public-api/common/vector-wrapper.h>
+#include <memory>
+#include <string_view>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
+{
+
+class DALI_SCENE3D_API ShaderDefinitionOption
+{
+public:
+  enum class Type
+  {
+    GLTF_CHANNELS = 0,
+    THREE_TEXTURE,
+    BASE_COLOR_TEXTURE,
+    METALLIC_ROUGHNESS_TEXTURE,
+    NORMAL_TEXTURE,
+    OCCLUSION,
+    EMISSIVE,
+    ALPHA_TEST,
+    SUBSURFACE,
+    SPECULAR,
+    SPECULAR_COLOR,
+    SKINNING,
+    FLIP_UVS_VERTICAL,
+    COLOR_ATTRIBUTE,
+    VEC4_TANGENT,
+    MORPH_POSITION,
+    MORPH_NORMAL,
+    MORPH_TANGENT,
+    MORPH_VERSION_2_0
+  };
+
+public:
+  /**
+   * @brief Sets transparency option.
+   */
+  void SetTransparency();
+
+  /**
+   * @brief Adds new shader definition option.
+   * If the option is already added, nothin is changed.
+   *
+   * @param[in] shaderDefinitionOptionType Option to be added,
+   */
+  void AddOption(Type shaderDefinitionOptionType);
+
+  /**
+   * @brief Retrieves current shader option hash
+   *
+   * @return Hash value of currently added options.
+   */
+  uint64_t GetOptionHash() const;
+
+  /**
+   * @brief Retrieves a list of define keywords.
+   *
+   * @param[out] defines A list of define keywords those are used in this option.
+   */
+  void GetDefines(std::vector<std::string>& defines) const;
+
+  /**
+   * @brief Retrieves a single shader define keyword of input type.
+   *
+   * @param[in] shaderDefinitionOptionType Shader definition option type to know its keyword.
+   * @return string keyword of shader define.
+   */
+  static std::string_view GetDefineKeyword(Type shaderDefinitionOptionType);
+
+private:
+  uint64_t mOptionHash{0u};
+};
+
+} // namespace Dali::Scene3D::Loader
+
+#endif // DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_
index 765d304..6ae5aa0 100644 (file)
@@ -858,7 +858,7 @@ void TextEditor::OnKeyInputFocusGained()
     // When window gain lost focus, the InputMethodContext is deactivated. Thus when window gain focus again, the InputMethodContext must be activated.
     mInputMethodContext.SetRestoreAfterFocusLost(true);
   }
-  ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
+  TextClipboardEventNotifier notifier(TextClipboardEventNotifier::Get());
 
   if(notifier)
   {
@@ -888,7 +888,7 @@ void TextEditor::OnKeyInputFocusLost()
 
     mInputMethodContext.EventReceivedSignal().Disconnect(this, &TextEditor::OnInputMethodContextEvent);
   }
-  ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
+  TextClipboardEventNotifier notifier(TextClipboardEventNotifier::Get());
 
   if(notifier)
   {
@@ -1286,7 +1286,7 @@ void TextEditor::GetHandleImagePropertyValue(Property::Value& value, Text::Handl
   }
 }
 
-void TextEditor::OnClipboardTextSelected(ClipboardEventNotifier& clipboard)
+void TextEditor::OnClipboardTextSelected(TextClipboardEventNotifier& clipboard)
 {
   mController->PasteClipboardItemEvent();
 }
index 117a09b..a4491e1 100644 (file)
@@ -20,7 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/accessibility.h>
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard-event-notifier.h>
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
 #include <dali/devel-api/atspi-interfaces/editable-text.h>
 #include <dali/devel-api/atspi-interfaces/hypertext.h>
@@ -449,9 +449,9 @@ private: // Implementation
 
   /**
    * @brief Callback when Clipboard signals an item should be pasted
-   * @param[in] clipboard handle to Clipboard Event Notifier
+   * @param[in] clipboard handle to TextClipboard Event Notifier
    */
-  void OnClipboardTextSelected(ClipboardEventNotifier& clipboard);
+  void OnClipboardTextSelected(TextClipboardEventNotifier& clipboard);
 
   /**
    * @brief Get a Property Map for the image used for the required Handle Image
index 499121a..658bb9a 100644 (file)
@@ -765,7 +765,7 @@ void TextField::OnKeyInputFocusGained()
     // When window gain lost focus, the inputMethodContext is deactivated. Thus when window gain focus again, the inputMethodContext must be activated.
     mInputMethodContext.SetRestoreAfterFocusLost(true);
   }
-  ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
+  TextClipboardEventNotifier notifier(TextClipboardEventNotifier::Get());
 
   if(notifier)
   {
@@ -794,7 +794,7 @@ void TextField::OnKeyInputFocusLost()
 
     mInputMethodContext.EventReceivedSignal().Disconnect(this, &TextField::OnInputMethodContextEvent);
   }
-  ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
+  TextClipboardEventNotifier notifier(TextClipboardEventNotifier::Get());
 
   if(notifier)
   {
@@ -1118,7 +1118,7 @@ void TextField::EnableClipping()
   }
 }
 
-void TextField::OnClipboardTextSelected(ClipboardEventNotifier& clipboard)
+void TextField::OnClipboardTextSelected(TextClipboardEventNotifier& clipboard)
 {
   mController->PasteClipboardItemEvent();
 }
index fe5056e..36fe57f 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard-event-notifier.h>
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
 #include <dali/devel-api/atspi-interfaces/editable-text.h>
 #include <dali/devel-api/atspi-interfaces/hypertext.h>
@@ -421,9 +421,9 @@ private: // Implementation
 
   /**
    * @brief Callback when Clipboard signals an item should be pasted
-   * @param[in] clipboard handle to Clipboard Event Notifier
+   * @param[in] clipboard handle to TextClipboard Event Notifier
    */
-  void OnClipboardTextSelected(ClipboardEventNotifier& clipboard);
+  void OnClipboardTextSelected(TextClipboardEventNotifier& clipboard);
 
   /**
    * @brief Get a Property Map for the image used for the required Handle Image
index e55a0e2..3cf8bf5 100644 (file)
@@ -32,7 +32,6 @@
 
 namespace Dali::Toolkit::ParticleSystem::Internal
 {
-
 constexpr uint32_t DEFAULT_PARTICLE_COUNT = 100u; ///< Default number of particles in system if not set by user
 
 /**
@@ -126,7 +125,7 @@ ParticleSystem::ParticleModifier ParticleEmitter::GetModifierAt(uint32_t index)
 
 void ParticleEmitter::RemoveModifierAt(uint32_t index)
 {
-  mModifiers.erase(mModifiers.begin()+index);
+  mModifiers.erase(mModifiers.begin() + index);
 }
 
 void ParticleEmitter::Start()
@@ -340,10 +339,7 @@ void ParticleEmitter::UpdateModifierMT(Dali::Toolkit::ParticleSystem::ParticleMo
     }
 
     updateTasks.emplace_back(GetImplementation(modifier), mParticleList, index, count);
-    tasks.emplace_back([&task = updateTasks.back()](uint32_t n)
-                       {
-      //printf("Updating modifier: %d\n", n);
-      task.Update(); });
+    tasks.emplace_back([&task = updateTasks.back()](uint32_t n) { task.Update(); });
   }
 
   auto future = threadPool.SubmitTasks(tasks, 0);
@@ -424,6 +420,14 @@ ParticleEmitter::ParticleEmitter()
   SetParticleCount(DEFAULT_PARTICLE_COUNT);
 }
 
+ParticleEmitter::~ParticleEmitter()
+{
+  if(mParticleRenderer)
+  {
+    GetImplementation(mParticleRenderer).PrepareToDie();
+  }
+}
+
 } // namespace Dali::Toolkit::ParticleSystem::Internal
 namespace Dali::Toolkit::ParticleSystem
 {
@@ -436,8 +440,7 @@ Dali::ThreadPool& GetThreadPool()
   // NOTE: this function shouldn't be called from multiple thread anyway
   if(!gThreadPool)
   {
-    std::call_once(onceFlag, [&threadPool = gThreadPool]
-                   { threadPool = std::make_unique<Dali::ThreadPool>();
+    std::call_once(onceFlag, [&threadPool = gThreadPool] { threadPool = std::make_unique<Dali::ThreadPool>();
                      threadPool->Initialize(4u); });
   }
 
index 2f1dcc7..4b09f2b 100644 (file)
@@ -49,7 +49,7 @@ public:
   /**
    * @brief Destructor
    */
-  ~ParticleEmitter() override = default;
+  ~ParticleEmitter() override;
 
   /**
    * @brief Tests whether emitter is complete (ready for simulation)
index c73f856..b9e689f 100644 (file)
@@ -454,4 +454,12 @@ bool ParticleRenderer::Initialize()
   return false;
 }
 
+void ParticleRenderer::PrepareToDie()
+{
+  if(mStreamBuffer)
+  {
+    mStreamBuffer.ClearVertexBufferUpdateCallback();
+  }
+}
+
 } // namespace Dali::Toolkit::ParticleSystem::Internal
\ No newline at end of file
index bcdb262..59bee33 100644 (file)
@@ -62,6 +62,8 @@ public:
 
   bool Initialize();
 
+  void PrepareToDie();
+
   void SetEmitter(ParticleSystem::Internal::ParticleEmitter* emitter);
 
   void UpdateParticlesTask(Internal::ParticleList& list,
index e280739..4cff878 100644 (file)
@@ -19,7 +19,7 @@
 #include <dali-toolkit/internal/text/controller/text-controller-event-handler.h>
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard-event-notifier.h>
 #include <dali/devel-api/adaptor-framework/key-devel.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/trace.h>
@@ -895,7 +895,7 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE
 void Controller::EventHandler::PasteClipboardItemEvent(Controller& controller)
 {
   // Retrieve the clipboard contents first
-  ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
+  TextClipboardEventNotifier notifier(TextClipboardEventNotifier::Get());
   std::string            stringToPaste(notifier.GetContent());
 
   // Commit the current pre-edit text; the contents of the clipboard should be appended
index 656b9bf..1844cb0 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard.h>
+#include <dali/devel-api/adaptor-framework/text-clipboard.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <dali/public-api/rendering/shader.h>
 
@@ -371,9 +371,9 @@ struct Controller::Impl
     mModel = Model::New();
 
     mFontClient = TextAbstraction::FontClient::Get();
-    if(mEditableControlInterface != nullptr && Clipboard::IsAvailable())
+    if(mEditableControlInterface != nullptr && TextClipboard::IsAvailable())
     {
-      mClipboard = Clipboard::Get();
+      mClipboard = TextClipboard::Get();
     }
 
     mView.SetVisualModel(mModel->mVisualModel);
@@ -568,7 +568,7 @@ struct Controller::Impl
   {
     if(!mClipboard)
     {
-      mClipboard = Clipboard::Get();
+      mClipboard = TextClipboard::Get();
     }
 
     return mClipboard != nullptr ? true : false;
@@ -576,13 +576,13 @@ struct Controller::Impl
 
   bool IsClipboardEmpty()
   {
-    bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.NumberOfItems());
+    bool result(TextClipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.NumberOfItems());
     return !result; // If NumberOfItems greater than 0, return false
   }
 
   bool IsClipboardVisible()
   {
-    bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.IsVisible());
+    bool result(TextClipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.IsVisible());
     return result;
   }
 
@@ -1016,7 +1016,7 @@ public:
   OutlineDefaults*             mOutlineDefaults;            ///< Avoid allocating this when the user does not specify outline parameters.
   EventData*                   mEventData;                  ///< Avoid allocating everything for text input until EnableTextInput().
   TextAbstraction::FontClient  mFontClient;                 ///< Handle to the font client.
-  Clipboard                    mClipboard;                  ///< Handle to the system clipboard
+  TextClipboard                mClipboard;                  ///< Handle to the system clipboard
   View                         mView;                       ///< The view interface to the rendering back-end.
   MetricsPtr                   mMetrics;                    ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
   Layout::Engine               mLayoutEngine;               ///< The layout engine.
index 67cff0f..7b8ef29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -32,9 +32,8 @@ namespace Toolkit
 {
 namespace Internal
 {
-
-SvgTask::SvgTask(VectorImageRenderer vectorRenderer, CallbackBase* callback)
-: AsyncTask(callback),
+SvgTask::SvgTask(VectorImageRenderer vectorRenderer, CallbackBase* callback, AsyncTask::PriorityType priorityType)
+: AsyncTask(callback, priorityType),
   mVectorRenderer(vectorRenderer),
   mHasSucceeded(false)
 {
@@ -56,7 +55,7 @@ VectorImageRenderer SvgTask::GetRenderer()
 }
 
 SvgLoadingTask::SvgLoadingTask(VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, CallbackBase* callback)
-: SvgTask(vectorRenderer, callback),
+: SvgTask(vectorRenderer, callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
   mUrl(url),
   mDpi(dpi)
 {
index 31855b9..89d8f55 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_SVG_TASK_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -55,8 +55,9 @@ public:
    * Constructor
    * @param[in] vectorRenderer The vector rasterizer.
    * @param[in] callback The callback that is called when the operation is completed.
+   * @param[in] priorityType The priority of this task.
    */
-  SvgTask(VectorImageRenderer vectorRenderer, CallbackBase* callback);
+  SvgTask(VectorImageRenderer vectorRenderer, CallbackBase* callback, AsyncTask::PriorityType priorityType = AsyncTask::PriorityType::DEFAULT);
 
   /**
    * Destructor.
index b82d80e..89e0427 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 31;
+const unsigned int TOOLKIT_MICRO_VERSION = 32;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 0fb2797..a498b93 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.2.31
+Version:    2.2.32
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT