[Tizen] Reset to 2.3.44 15/319015/2 accepted/tizen/unified/20241015.153122 accepted/tizen/unified/x/20241016.023854
authorEunki Hong <eunkiki.hong@samsung.com>
Sat, 12 Oct 2024 13:32:14 +0000 (22:32 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Sat, 12 Oct 2024 14:28:50 +0000 (23:28 +0900)
Change-Id: I48dcd0132848a9b65524ef89f9100335fe37d34d
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
38 files changed:
automated-tests/src/dali-internal/utc-Dali-Internal-Shader.cpp
automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali/utc-Dali-ConditionalWait.cpp
automated-tests/src/dali/utc-Dali-CustomActor.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
automated-tests/src/dali/utc-Dali-WeakHandle.cpp
build/scripts/dali_env
dali/devel-api/threading/conditional-wait.cpp
dali/devel-api/threading/conditional-wait.h
dali/graphics-api/graphics-controller.h
dali/graphics-api/graphics-types.h
dali/integration-api/file.list
dali/integration-api/shader-integ.cpp [new file with mode: 0644]
dali/integration-api/shader-integ.h [new file with mode: 0644]
dali/internal/common/core-impl.cpp
dali/internal/common/image-attributes.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/actor-parent-impl.cpp
dali/internal/event/actors/custom-actor-internal.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/effects/shader-factory.cpp
dali/internal/event/effects/shader-factory.h
dali/internal/event/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/internal/event/rendering/shader-impl.cpp
dali/internal/event/rendering/shader-impl.h
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-manager.cpp
dali/public-api/actors/actor-enumerations.h
dali/public-api/actors/custom-actor-impl.cpp
dali/public-api/actors/custom-actor-impl.h
dali/public-api/dali-core-version.cpp
dali/public-api/images/image-operations.h
packaging/dali.spec

index 64fcd73318e5a423a6ec10b1a299298c5d3734d8..5f294a4d15f30ee3ed0026725ab7b848bfbceab1 100644 (file)
@@ -16,6 +16,7 @@
 */
 
 #include <dali-test-suite-utils.h>
+#include <dali/integration-api/shader-integ.h>
 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/effects/shader-factory.h>
@@ -97,6 +98,49 @@ int UtcDaliShaderWithPrefixTestVersion(void)
   END_TEST;
 }
 
+int UtcDaliShaderWithPrefixTestVersion2(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test same case of UtcDaliShaderWithPrefixTestVersion with integration api");
+
+  std::string vertexShader =
+    "//@version 100\n"
+    "some code\n";
+  std::string fragmentShader =
+    "//@version 101\n"
+    "some code\n";
+
+  // Get prefix from graphics config.
+  auto vertexPrefix   = application.GetGlAbstraction().GetVertexShaderPrefix();
+  auto fragmentPrefix = application.GetGlAbstraction().GetFragmentShaderPrefix();
+
+  // And use GenerateTaggedShaderPrefix from integration-api.
+  vertexPrefix   = Dali::Integration::GenerateTaggedShaderPrefix(vertexPrefix);
+  fragmentPrefix = Dali::Integration::GenerateTaggedShaderPrefix(fragmentPrefix);
+
+  Dali::Shader shader = Dali::Shader::New(
+    vertexPrefix + vertexShader,
+    fragmentPrefix + fragmentShader);
+
+  DALI_TEST_EQUALS(vertexPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+
+  // Test version number in the shader data
+  Dali::Internal::ThreadLocalStorage& tls           = Dali::Internal::ThreadLocalStorage::Get();
+  Dali::Internal::ShaderFactory&      shaderFactory = tls.GetShaderFactory();
+  size_t                              shaderHash;
+  Internal::ShaderDataPtr             shaderData = shaderFactory.Load(vertexShader, fragmentShader, {}, {}, "", shaderHash);
+
+  bool dataValid = (shaderData != nullptr);
+  DALI_TEST_EQUALS(dataValid, true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(shaderData->GetVertexShaderVersion(), 100, TEST_LOCATION);
+  DALI_TEST_EQUALS(shaderData->GetFragmentShaderVersion(), 101, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliInternalShaderSaveAndLoad01(void)
 {
   TestApplication application;
index db0c78fbf70c7fd133291ec0165a27ba57edaefe..dcb2cd88a188b468add1326e4ce3b2a49a7ef226 100644 (file)
@@ -169,6 +169,10 @@ public:
   float TestCalculateChildSizeBase(const Dali::Actor& child, Dali::Dimension::Type dimension);
   bool  TestRelayoutDependentOnChildrenBase(Dali::Dimension::Type dimension);
 
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+  }
+
 public:
   Dali::Property::Index    mDaliProperty;
   std::vector<std::string> mMethodsCalled;
@@ -515,6 +519,10 @@ public:
   {
     return false;
   }
+
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+  }
 };
 
 } //namespace Impl
index f0bc4d6d5dde5f659628ac54300d245fe7d59403..114879fb4faa9ec6e36cc41e6f9dba7419e38aef 100644 (file)
@@ -1505,4 +1505,22 @@ Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::ReleaseTextureFro
   return texture;
 }
 
+bool TestGraphicsController::HasClipMatrix() const
+{
+  return true;
+}
+
+const Matrix& TestGraphicsController::GetClipMatrix() const
+{
+  // This matrix transforms from GL -> Vulkan clip space
+  constexpr float VULKAN_CLIP_MATRIX_DATA[] = {
+    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f};
+  static const Matrix VULKAN_CLIP_MATRIX(VULKAN_CLIP_MATRIX_DATA);
+  static const Matrix IDENTITY = Matrix::IDENTITY;
+
+  // For now, return IDENTITY to stay in GL clip space.
+  // @todo Add test toggle
+  return IDENTITY;
+}
+
 } // namespace Dali
index e21c30400f009814a08b0683288f1a7d6f5b05f3..2b0a9b97aaedb4ab9ee2facf08ba104f15b74ca6 100644 (file)
@@ -422,6 +422,9 @@ public: // ResourceId relative API.
    */
   Graphics::UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) override;
 
+  bool          HasClipMatrix() const override;
+  const Matrix& GetClipMatrix() const override;
+
 public: // Test Functions
   void SetAutoAttrCreation(bool v)
   {
@@ -499,14 +502,14 @@ public: // Test Functions
                                uint32_t                                      elementStrideInBytes)
   {
     TestGraphicsReflection::TestUniformInfo info;
-    info.name          = std::move(name);
-    info.type          = type;
-    info.uniformClass  = Graphics::UniformClass::UNIFORM;
-    info.numElements   = elementCount;
-    info.locations     = {0};
-    info.bufferIndex   = 0;                    // this will update when AddCustomUniformBlock called
-
-    auto retval= GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes);
+    info.name         = std::move(name);
+    info.type         = type;
+    info.uniformClass = Graphics::UniformClass::UNIFORM;
+    info.numElements  = elementCount;
+    info.locations    = {0};
+    info.bufferIndex  = 0; // this will update when AddCustomUniformBlock called
+
+    auto retval        = GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes);
     info.elementStride = std::max(retval.first, retval.second);
     info.offsets       = {blockInfo.size};
     blockInfo.size += (elementCount == 0 ? 1 : elementCount) * std::max(retval.first, retval.second);
@@ -567,4 +570,4 @@ public:
 
 } // namespace Dali
 
-#endif //TEST_GRAPHICS_CONTROLLER_H
+#endif // TEST_GRAPHICS_CONTROLLER_H
index 71fe305a9b97403fc3408a35305885ad64681aaa..8641d2d4ce62b3b90dbdacd72f2d7bef38274c93 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -77,6 +77,29 @@ class WorkerThreadWaitN : public Thread
   }
 };
 
+class WorkerThreadWaitUntilN : public Thread
+{
+public:
+  WorkerThreadWaitUntilN()
+  : Thread()
+  {
+    auto now          = std::chrono::steady_clock::now();
+    auto waitDuration = std::chrono::milliseconds(100); // 0.1 second
+
+    mWaitUntilTimePoint = std::chrono::time_point_cast<ConditionalWait::TimePoint::duration>(now + waitDuration);
+  }
+
+  virtual void Run()
+  {
+    ConditionalWait::ScopedLock lock(*gConditionalWait);
+
+    gConditionalWait->WaitUntil(lock, mWaitUntilTimePoint);
+  }
+
+private:
+  ConditionalWait::TimePoint mWaitUntilTimePoint;
+};
+
 } // namespace
 
 int UtcConditionalWait1P(void)
@@ -254,6 +277,77 @@ int UtcConditionalWait6P(void)
   END_TEST;
 }
 
+int UtcConditionalWaitUntilP1(void)
+{
+  tet_infoline("Testing ConditionalWait - scenario:  waituntil now + 100 ms - with 4 threads. No notify");
+
+  auto utcStartTime = std::chrono::steady_clock::now();
+
+  // initialize values
+  gConditionalWait = new ConditionalWait();
+
+  WorkerThreadWaitUntilN thread1;
+  thread1.Start();
+  WorkerThreadWaitUntilN thread2;
+  thread2.Start();
+  WorkerThreadWaitUntilN thread3;
+  thread3.Start();
+  WorkerThreadWaitUntilN thread4;
+  thread4.Start();
+
+  // Let we check thread join well without any notification
+
+  thread1.Join();
+  thread2.Join();
+  thread3.Join();
+  thread4.Join();
+
+  DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
+
+  auto utcFinishedTime = std::chrono::steady_clock::now();
+
+  // Check thread join spened at least 100ms
+  auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(utcFinishedTime - utcStartTime).count();
+
+  DALI_TEST_GREATER(elapsedTime, static_cast<int64_t>(100 - 1), TEST_LOCATION); // 100ms is the minimum time for the threads to wait
+
+  delete gConditionalWait;
+  END_TEST;
+}
+
+int UtcConditionalWaitUntilP2(void)
+{
+  tet_infoline("Testing ConditionalWait - scenario:  waituntil now + 100 ms - notify with 4 threads");
+
+  // initialize values
+  gConditionalWait = new ConditionalWait();
+
+  WorkerThreadWaitUntilN thread1;
+  thread1.Start();
+  WorkerThreadWaitUntilN thread2;
+  thread2.Start();
+  WorkerThreadWaitUntilN thread3;
+  thread3.Start();
+  WorkerThreadWaitUntilN thread4;
+  thread4.Start();
+
+  // Notify with scoped lock
+  {
+    ConditionalWait::ScopedLock lock(*gConditionalWait);
+    gConditionalWait->Notify(lock);
+  }
+
+  thread1.Join();
+  thread2.Join();
+  thread3.Join();
+  thread4.Join();
+
+  DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
+
+  delete gConditionalWait;
+  END_TEST;
+}
+
 int UtcConditionalWaitNonCopyable(void)
 {
   // we want to make sure that ConditionalWait is not copyable (its copy constructor is not defined)
index 1df10a6df91c3e7ae546273476fccc2409b9b722..43ffeac65bd6fce7ce782323ca111c4a3bd5288d 100644 (file)
@@ -1464,6 +1464,10 @@ struct UnregisteredCustomActor : public Dali::CustomActorImpl
   virtual void OnLayoutNegotiated(float size, Dimension::Type dimension)
   {
   }
+
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+  }
 };
 } // namespace Impl
 struct UnregisteredCustomActor : public Dali::CustomActor
@@ -1709,3 +1713,184 @@ int UtcDaliCustomActorComponentPropertyConstraintsP(void)
 
   END_TEST;
 }
+
+namespace Impl
+{
+
+class OffScreenCustomActor : public UnregisteredCustomActor
+{
+public:
+  void OnSceneConnection(int depth) override
+  {
+    tet_printf("tyty : %d\n", GetOffScreenRenderableType());
+    Dali::Integration::Scene scene = Dali::Integration::Scene::Get(Self());
+    if(scene)
+    {
+      mScene                  = scene;
+      RenderTaskList taskList = scene.GetRenderTaskList();
+      mForwardRenderTask      = taskList.CreateTask();
+      mBackwardRenderTask     = taskList.CreateTask();
+      FrameBuffer forwardFrameBuffer = FrameBuffer::New(1, 1);
+      FrameBuffer backwardFrameBuffer = FrameBuffer::New(1, 1);
+
+      mForwardRenderTask.SetFrameBuffer(forwardFrameBuffer);
+      mBackwardRenderTask.SetFrameBuffer(backwardFrameBuffer);
+    }
+  }
+
+  void OnSceneDisconnection() override
+  {
+    Dali::Integration::Scene scene = mScene.GetHandle();
+    if(scene)
+    {
+      RenderTaskList taskList = scene.GetRenderTaskList();
+      taskList.RemoveTask(mForwardRenderTask);
+      taskList.RemoveTask(mBackwardRenderTask);
+    }
+    mForwardRenderTask.Reset();
+    mBackwardRenderTask.Reset();
+    mScene.Reset();
+  }
+
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+    tasks.clear();
+    if(isForward && GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD && mForwardRenderTask)
+    {
+      tasks.push_back(mForwardRenderTask);
+    }
+    if(!isForward && GetOffScreenRenderableType() & OffScreenRenderable::Type::BACKWARD && mBackwardRenderTask)
+    {
+      tasks.push_back(mBackwardRenderTask);
+    }
+  }
+
+  Dali::WeakHandle<Dali::Integration::Scene> mScene;
+  Dali::RenderTask                           mForwardRenderTask;
+  Dali::RenderTask                           mBackwardRenderTask;
+};
+
+} // namespace Impl
+
+class OffScreenCustomActor : public UnregisteredCustomActor
+{
+public:
+  static OffScreenCustomActor New(OffScreenRenderable::Type type)
+  {
+    Impl::OffScreenCustomActor* impl = new Impl::OffScreenCustomActor;
+    OffScreenCustomActor        custom(*impl, type); // takes ownership
+    return custom;
+  }
+  OffScreenCustomActor()
+  {
+  }
+  ~OffScreenCustomActor()
+  {
+  }
+  OffScreenCustomActor(Internal::CustomActor* impl)
+  : UnregisteredCustomActor(impl)
+  {
+  }
+  OffScreenCustomActor(Impl::OffScreenCustomActor& impl, OffScreenRenderable::Type type)
+  : UnregisteredCustomActor(impl)
+  {
+    mImpl = &impl;
+    mImpl->SetOffScreenRenderableType(type);
+  }
+  Dali::RenderTask GetForwardRenderTask()
+  {
+    return mImpl->mForwardRenderTask;
+  }
+  Dali::RenderTask GetBackwardRenderTask()
+  {
+    return mImpl->mBackwardRenderTask;
+  }
+  OffScreenRenderable::Type GetOffScreenRenderableType()
+  {
+    tet_printf("type : %d\n", mImpl->GetOffScreenRenderableType());
+    return mImpl->GetOffScreenRenderableType();
+  }
+
+  Impl::OffScreenCustomActor* mImpl;
+};
+
+int UtcDaliCustomActorReordering(void)
+{
+  TestApplication application; // Need the type registry
+
+  DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION);
+
+  /**
+   *          Al
+   *       /     \
+   *      Bb      Cl
+   *     / \     / \
+   *    D   Efb Jb  K
+   *       / \
+   *      Fb   Gf
+   *          / \
+   *         H   I
+   * 
+   * A, C are Layer. C has smaller Depth value than A.
+   * B, E, F, G, and J are OffScreenCustomActor.
+   * B, F, and J are Type BACKWARD.
+   * E and G are Type FORWARD.
+   *
+   * After reordering, The order of OrderIndex of each RenderTask becomes
+   * G(Forward) - F(Backward) - E(Forward) - J(BACKWARD) - B(BACKWARD) - E(BACKWARD)
+   */
+
+  Layer A_layer = Layer::New();
+  OffScreenCustomActor B_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+  Layer C_layer = Layer::New();
+  Actor D_actor = Actor::New();
+  OffScreenCustomActor E_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BOTH);
+  OffScreenCustomActor F_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+  OffScreenCustomActor G_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::FORWARD);
+  Actor H_actor = Actor::New();
+  Actor I_actor = Actor::New();
+  OffScreenCustomActor J_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+
+  A_layer.Add(B_offScreenCustomActor);
+  A_layer.Add(C_layer);
+  B_offScreenCustomActor.Add(D_actor);
+  B_offScreenCustomActor.Add(E_offScreenCustomActor);
+  E_offScreenCustomActor.Add(F_offScreenCustomActor);
+  E_offScreenCustomActor.Add(G_offScreenCustomActor);
+  G_offScreenCustomActor.Add(H_actor);
+  G_offScreenCustomActor.Add(I_actor);
+  C_layer.Add(J_offScreenCustomActor);
+
+  DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION);
+  tet_printf("task cnt before : %d\n", application.GetScene().GetRenderTaskList().GetTaskCount());
+
+  application.GetScene().Add(A_layer);
+
+  DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 11, TEST_LOCATION);
+
+  C_layer.MoveBelow(A_layer);
+
+  application.GetScene().GetRenderTaskList().GetTaskCount();
+
+  tet_printf("task cnt after : %d\n", application.GetScene().GetRenderTaskList().GetTaskCount());
+  tet_printf("c depth : %d, a depth : %d\n", C_layer.GetProperty<int>(Dali::Layer::Property::DEPTH), A_layer.GetProperty<int>(Dali::Layer::Property::DEPTH));
+  tet_printf("c id : %d, a id : %d\n", C_layer.GetProperty<int>(Dali::Actor::Property::ID), A_layer.GetProperty<int>(Dali::Actor::Property::ID));
+
+  DALI_TEST_CHECK(C_layer.GetProperty<int>(Dali::Layer::Property::DEPTH) < A_layer.GetProperty<int>(Dali::Layer::Property::DEPTH));
+
+  application.SendNotification();
+
+  tet_printf("B task order F : %d, task order B : %d\n", B_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  tet_printf("E task order F : %d, task order B : %d\n", E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), E_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  tet_printf("F task order F : %d, task order B : %d\n", F_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  tet_printf("G task order F : %d, task order B : %d\n", G_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), G_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  tet_printf("J task order F : %d, task order B : %d\n", J_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+
+  DALI_TEST_CHECK(G_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex() < F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  DALI_TEST_CHECK(F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex());
+  DALI_TEST_CHECK(E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex() < J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  DALI_TEST_CHECK(J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+  DALI_TEST_CHECK(B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < E_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+
+  END_TEST;
+}
\ No newline at end of file
index 72b3893dc37df7fb2e03e91507ac9d09405a321d..db59e42577f836f50dd93c9dded86deca3ba8e8b 100644 (file)
@@ -5138,7 +5138,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
   RenderTask     renderTask1    = renderTaskList.CreateTask();
 
   application.SendNotification();
-  uint32_t answer1[2] = {0u, 0u};
+  int32_t answer1[2] = {INT32_MIN, 0};
   DALI_TEST_EQUALS(2, renderTaskList.GetTaskCount(), TEST_LOCATION);
   for(uint32_t i = 0; i < 2; ++i)
   {
@@ -5147,7 +5147,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   RenderTask renderTask2 = renderTaskList.CreateTask();
   application.SendNotification();
-  int32_t answer2[3] = {0u, 0u, 0u};
+  int32_t answer2[3] = {INT32_MIN, 0, 0};
   DALI_TEST_EQUALS(3, renderTaskList.GetTaskCount(), TEST_LOCATION);
   for(uint32_t i = 0; i < 3; ++i)
   {
@@ -5156,7 +5156,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   RenderTask renderTask3 = renderTaskList.CreateTask();
   application.SendNotification();
-  int32_t answer3[4] = {0u, 0u, 0u, 0u};
+  int32_t answer3[4] = {INT32_MIN, 0, 0, 0};
   DALI_TEST_EQUALS(4, renderTaskList.GetTaskCount(), TEST_LOCATION);
   for(uint32_t i = 0; i < 4; ++i)
   {
@@ -5165,7 +5165,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   renderTask1.SetOrderIndex(3);
   application.SendNotification();
-  int32_t answer4[4] = {0u, 0u, 0u, 3u};
+  int32_t answer4[4] = {INT32_MIN, 0, 0, 3};
   for(uint32_t i = 0; i < 4; ++i)
   {
     DALI_TEST_EQUALS(answer4[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
@@ -5173,7 +5173,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   renderTask2.SetOrderIndex(7);
   application.SendNotification();
-  int32_t answer5[4] = {0u, 0u, 3u, 7u};
+  int32_t answer5[4] = {INT32_MIN, 0, 3, 7};
   for(uint32_t i = 0; i < 4; ++i)
   {
     DALI_TEST_EQUALS(answer5[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
@@ -5183,7 +5183,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
   scene.GetOverlayLayer();
   application.SendNotification();
   DALI_TEST_EQUALS(5, renderTaskList.GetTaskCount(), TEST_LOCATION);
-  int32_t answer6[5] = {0u, 0u, 3u, 7u, INT32_MAX};
+  int32_t answer6[5] = {INT32_MIN, 0, 3, 7, INT32_MAX};
   for(uint32_t i = 0; i < 5; ++i)
   {
     DALI_TEST_EQUALS(answer6[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
@@ -5191,7 +5191,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   renderTask3.SetOrderIndex(4);
   application.SendNotification();
-  int32_t answer7[5] = {0u, 3u, 4u, 7u, INT32_MAX};
+  int32_t answer7[5] = {INT32_MIN, 3, 4, 7, INT32_MAX};
   for(uint32_t i = 0; i < 5; ++i)
   {
     DALI_TEST_EQUALS(answer7[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
@@ -5199,7 +5199,7 @@ int UtcDaliRenderTaskOrderIndex01(void)
 
   renderTask2.SetOrderIndex(2);
   application.SendNotification();
-  int32_t answer8[5] = {0u, 2u, 3u, 4u, INT32_MAX};
+  int32_t answer8[5] = {INT32_MIN, 2, 3, 4, INT32_MAX};
   for(uint32_t i = 0; i < 5; ++i)
   {
     DALI_TEST_EQUALS(answer8[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
index 9a2ab5852ccda725928a317bb37d62c35724af4f..c1899a621de2f45f66dae17758e8aa487994cfaf 100644 (file)
@@ -204,6 +204,10 @@ struct MyTestCustomActor : public CustomActorImpl
     return false;
   }
 
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+  }
+
 public:
   SignalType mSignal;
 };
index 49467005fe512873e15ab5471234373b63aed20a..77d698120613a9bc5bda054de1bc28ef54ed6d69 100644 (file)
@@ -113,6 +113,10 @@ struct MyTestCustomActor : public CustomActorImpl
     return false;
   }
 
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+  {
+  }
+
 public:
   SignalType mSignal;
 };
index 8ff18c6a2e13f745865e22cbb685685c54a62c90..adabf677d5ca7c1ade2b2fbd0af664001e107b19 100755 (executable)
@@ -165,7 +165,7 @@ my $opt_help=0;
 my $opt_man=0;
 my $opt_vk_version="1.3.280.1";
 my $opt_vulkan=undef;
-my $VULKAN_ENV="";
+my $opt_usd=0;
 
 GetOptions("create"     => \$opt_create,
            "envfile=s"  => \$opt_envfile,
@@ -173,6 +173,7 @@ GetOptions("create"     => \$opt_create,
            "setenv"     => \$opt_setenv,
            "help"       => \$opt_help,
            "vulkan:s"   => \$opt_vulkan,
+           "usd"        => \$opt_usd,
            "man"        => \$opt_man) or pod2usage(2);
 
 pod2usage(1) if $opt_help;
@@ -293,8 +294,23 @@ EOF
 }
 
 ################################################################################
-sub vulkan_env
+sub download_archive
 {
+    my ($archive, $url, $download_info) = @_;
+
+    # Avoid excessive downloading of the same file
+    if(! -e "/tmp/$archive")
+    {
+        print "Downloading $download_info\nfrom: $url\n";
+        system('wget','-P','/tmp',$url);
+        die "Can't download archive" if(! -e "/tmp/$archive");
+    }
+}
+
+sub untar_archive
+{
+    my $archive=shift;
+    system('tar','-xf',"/tmp/$archive", '--checkpoint=5000', '--checkpoint-action=ttyout=.');
 }
 
 sub install_vulkan
@@ -303,20 +319,13 @@ sub install_vulkan
     {
         my $archive="vulkansdk-linux-x86_64-${opt_vk_version}.tar.xz";
         my $url="https://sdk.lunarg.com/sdk/download/${opt_vk_version}/linux/$archive";
-
-        # Avoid excessive downloading of the same file
-        if(! -e "/tmp/$archive")
-        {
-            print "Downloading Vulkan SDK version ${opt_vk_version}\nfrom: $url\n";
-            system('wget','-P','/tmp',$url);
-            die "Can't download archive" if(! -e "/tmp/$archive");
-        }
+        download_archive($archive, $url, "Vulkan SDK version ${opt_vk_version}");
 
         my $vulkan_install_path="$root_path/vulkan";
-        print "Unpacking archive\n";
+        print "Unpacking vulkan archive\n";
         mkpath($vulkan_install_path);
         chdir($vulkan_install_path);
-        system('tar','-xf',"/tmp/$archive", '--checkpoint=5000', '--checkpoint-action=ttyout=.');
+        untar_archive($archive);
         print("\n");
         chdir("$root_path/..");
 
@@ -373,6 +382,84 @@ EOF
     }
 }
 
+sub install_usd
+{
+    if($opt_usd)
+    {
+        my $boost_archive="boost-1.84.0.tar.gz";
+        my $boost_url="https://github.com/boostorg/boost/releases/download/boost-1.84.0/$boost_archive";
+        download_archive($boost_archive, $boost_url, "Boost");
+
+        my $tbb_archive="2019_U9.tar.gz";
+        my $tbb_url="https://github.com/oneapi-src/oneTBB/archive/refs/tags/$tbb_archive";
+        download_archive($tbb_archive, $tbb_url, "LibTBB");
+
+        my $openusd_archive="32-bit-arm-and-tizen-support.tar.gz";
+        my $openusd_url="https://github.com/dalihub/OpenUSD/archive/refs/tags/$openusd_archive";
+        download_archive($openusd_archive, $openusd_url, "OpenUSD");
+
+        my $usd_install_path=$install_path;
+        my $usd_source_path="$src_path/usd";
+
+        print "Unpacking Boost, TBB & OpenUSD archives\n";
+        mkpath($usd_source_path);
+        chdir($usd_source_path);
+        untar_archive($boost_archive);
+        untar_archive($tbb_archive);
+        untar_archive($openusd_archive);
+
+        mkpath("$usd_install_path/lib");
+        mkpath("$usd_install_path/include");
+
+        my $boost_source_path="$usd_source_path/boost-1.84.0";
+        print "Building Boost\n";
+        chdir("$boost_source_path");
+        system('cmake',"-DCMAKE_INSTALL_PREFIX=$usd_install_path", '.');
+        system('make','-j8','install');
+
+        my $tbb_source_path="$usd_source_path/oneTBB-2019_U9";
+        print "Building TBB\n";
+        chdir("$tbb_source_path");
+        system('make','-j8');
+        my $tbbBuildFolder=`make info | grep tbb_build_prefix | cut -d= -f 2`;
+        chomp($tbbBuildFolder);
+        $tbbBuildFolder=$tbbBuildFolder . "_release";
+        print "$tbbBuildFolder Hello";
+        system("install -m 644 ./build/$tbbBuildFolder/*.so* $usd_install_path/lib/");
+        system('cp','-rf','include/tbb',"$usd_install_path/include/");
+
+        my $openusd_source_path="$usd_source_path/OpenUSD-32-bit-arm-and-tizen-support";
+        print "Building USD\n";
+        chdir("$openusd_source_path");
+        system('cmake',
+               '-DPXR_ENABLE_PYTHON_SUPPORT=OFF',
+               '-DPXR_ENABLE_PTEX_SUPPORT=OFF',
+               '-DPXR_ENABLE_OPENVDB_SUPPORT=OFF',
+               '-DPXR_ENABLE_HDF5_SUPPORT=OFF',
+               '-DPXR_ENABLE_MATERIALX_SUPPORT=OFF',
+               '-DPXR_BUILD_IMAGING=OFF',
+               '-DPXR_BUILD_USD_IMAGING=OFF',
+               '-DPXR_BUILD_USDVIEW=OFF',
+               '-DPXR_BUILD_DOCUMENTATION=OFF',
+               '-DPXR_BUILD_HTML_DOCUMENTATION=OFF',
+               '-DPXR_BUILD_PYTHON_DOCUMENTATION=OFF',
+               '-DPXR_BUILD_TESTS=OFF',
+               '-DPXR_BUILD_EXAMPLES=OFF',
+               '-DPXR_BUILD_TUTORIALS=OFF',
+               '-DPXR_BUILD_USD_TOOLS=OFF',
+               '-DPXR_BUILD_MAYAPY_TESTS=OFF',
+               '-DPXR_BUILD_ANIMX_TESTS=OFF',
+               "-DTBB_ROOT_DIR=$usd_install_path",
+               "-DBOOST_ROOT=$usd_install_path",
+               "-DCMAKE_INSTALL_PREFIX=$usd_install_path",
+               '.'
+              );
+        system('make','-j8','install');
+
+        print("\n");
+        chdir("$root_path/..");
+    }
+}
 
 sub check_system_package
 {
@@ -433,7 +520,7 @@ sub check_source_packages
             {
                 print "Attempting to build $pkg\n";
                 # from https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/
-                run_command("cd /usr/src/gtest; sudo cmake CMakeLists.txt; sudo make; sudo cp *.a /usr/lib; cd -;");
+                run_command("cd /usr/src/gtest; sudo cmake CMakeLists.txt; sudo make; sudo cp lib/*.a /usr/lib; cd -;");
             }
         }
     }
@@ -755,6 +842,7 @@ if($opt_create)
     check_source_packages();
 
     install_vulkan();
+    install_usd();
     create_setenv();
 }
 elsif($opt_setenv)
@@ -811,6 +899,10 @@ Install the Vulkan SDK (By default, uses 1.3.280.1) with the optional version
 number. Adds several .pc files into dali-env/opt/lib/pkg-config directory,
 and requires a new environment file to be written.
 
+=item B<-u|--usd>
+
+Installs the OpenUSD library and its dependencies.
+
 =item B<-h|--help>
 
 Display this help
index 3259203648db462791fd0b416183c534d1e51957..3d6ec9bf7c683bcfdff8239e46d0d4b034f1cda9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ void ConditionalWait::Notify()
 void ConditionalWait::Notify(const ScopedLock& scope)
 {
   // Scope must be locked:
-  DALI_ASSERT_DEBUG(&scope.GetLockedWait() == this);
+  DALI_ASSERT_ALWAYS(&scope.GetLockedWait() == this);
 
   volatile unsigned int previousCount = mImpl->count;
 
@@ -127,7 +127,7 @@ void ConditionalWait::Wait()
 void ConditionalWait::Wait(const ScopedLock& scope)
 {
   // Scope must be locked:
-  DALI_ASSERT_DEBUG(&scope.GetLockedWait() == this);
+  DALI_ASSERT_ALWAYS(&scope.GetLockedWait() == this);
 
   ++(mImpl->count);
 
@@ -142,6 +142,32 @@ void ConditionalWait::Wait(const ScopedLock& scope)
   // passed in will unlock it in the caller.
 }
 
+void ConditionalWait::WaitUntil(const ScopedLock& scope, ConditionalWait::TimePoint timePoint)
+{
+  // Scope must be locked:
+  DALI_ASSERT_ALWAYS(&scope.GetLockedWait() == this);
+
+  ++(mImpl->count);
+
+  // conditional wait may wake up without anyone calling Notify
+  do
+  {
+    // wait while condition changes
+    if(mImpl->condition.wait_until(scope.mImpl->lock, timePoint) == std::cv_status::timeout)
+    {
+      // Pass-through for this wait request.
+      // Note that we should not wake-up other wait requests.
+      if(mImpl->count > 0u)
+      {
+        --mImpl->count;
+      }
+    }
+  } while(0 != mImpl->count);
+
+  // We return with our mutex locked safe in the knowledge that the ScopedLock
+  // passed in will unlock it in the caller.
+}
+
 unsigned int ConditionalWait::GetWaitCount() const
 {
   return mImpl->count;
index a18b93f5bae7ef125deadb346667d42ea1b8f57d..f0ea102df416111d6335305708618ed815264fc4 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_CONDITIONAL_WAIT_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <chrono> ///< for std::chrono::time_point
+
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 
@@ -65,6 +68,8 @@ public:
     const ScopedLock& operator=(const ScopedLock&);
   };
 
+  using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+
   /**
    * @brief Constructor, creates the internal synchronization objects
    */
@@ -114,6 +119,19 @@ public:
    */
   void Wait(const ScopedLock& scope);
 
+  /**
+   * @brief Wait until specific time point or another thread to notify us when the condition is true and we can continue
+   *
+   * Will always block current thread until Notify is called.
+   * Assumes that the ScopedLock object passed in has already locked the internal state of
+   * this object. Releases the lock while waiting and re-acquires it when returning
+   * from the wait.
+   * @param[in] scope A pre-existing lock on the internal state of this object.
+   * @param[in] timePoint Maximum time point to wait.
+   * @pre scope must have been passed this ConditionalWait during its construction.
+   */
+  void WaitUntil(const ScopedLock& scope, TimePoint timePoint);
+
   /**
    * @brief Return the count of threads waiting for this conditional
    * @return count of waits
index 466edfa82fa30847c20f157cf56991af2211b056..19009339bf0e4772ac96f88d04560cebd7a89632 100644 (file)
@@ -412,6 +412,20 @@ public: // ResourceId relative API.
    */
   virtual UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) = 0;
 
+  /**
+   * @brief Determine if the backend needs to multiply the projection matrix by a clip matrix
+   *
+   * @return TRUE if the graphics backend requires an alternative clip matrix
+   */
+  virtual bool HasClipMatrix() const = 0;
+
+  /**
+   * @brief Get the alternative clipping matrix.
+   *
+   * @return the clipping matrix
+   */
+  virtual const Matrix& GetClipMatrix() const = 0;
+
 protected:
   /**
    * Creates controller
index 77800058bbd632acd52e179756e67b200815519d..dab4ab641eb3d9e560b06846e219f0a99c32bd08 100644 (file)
@@ -80,7 +80,7 @@ struct Viewport
   float width    = 0.0f;
   float height   = 0.0f;
   float minDepth = 0.0f;
-  float maxDepth = 0.0f;
+  float maxDepth = 1.0f;
 };
 
 /**
index bf08a162bfe37aec44c466a13574c9def4d7d84e..d7feadfef7502374513d2e92339a9ab47eb7bb6f 100644 (file)
@@ -13,6 +13,7 @@ SET( platform_abstraction_src_files
    ${platform_abstraction_src_dir}/profiling.cpp
    ${platform_abstraction_src_dir}/render-task-list-integ.cpp
    ${platform_abstraction_src_dir}/scene.cpp
+   ${platform_abstraction_src_dir}/shader-integ.cpp
    ${platform_abstraction_src_dir}/testing.cpp
    ${platform_abstraction_src_dir}/texture-integ.cpp
    ${platform_abstraction_src_dir}/trace.cpp
@@ -53,6 +54,7 @@ SET( platform_abstraction_header_files
    ${platform_abstraction_src_dir}/resource-policies.h
    ${platform_abstraction_src_dir}/resource-types.h
    ${platform_abstraction_src_dir}/scene.h
+   ${platform_abstraction_src_dir}/shader-integ.h
    ${platform_abstraction_src_dir}/testing.h
    ${platform_abstraction_src_dir}/texture-integ.h
    ${platform_abstraction_src_dir}/trace.h
diff --git a/dali/integration-api/shader-integ.cpp b/dali/integration-api/shader-integ.cpp
new file mode 100644 (file)
index 0000000..4219395
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali/integration-api/shader-integ.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/rendering/shader-impl.h>
+
+namespace Dali::Integration
+{
+std::string GenerateTaggedShaderPrefix(const std::string& shaderPrefix)
+{
+  return Dali::Internal::Shader::GenerateTaggedShaderPrefix(shaderPrefix);
+}
+} // namespace Dali::Integration
diff --git a/dali/integration-api/shader-integ.h b/dali/integration-api/shader-integ.h
new file mode 100644 (file)
index 0000000..fea64a8
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef DALI_SHADER_INTEG_H
+#define DALI_SHADER_INTEG_H
+
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 INCLUDES
+#include <string> // std::string
+
+// INTERNAL INCLUDES
+#include <dali/public-api/rendering/shader.h>
+
+namespace Dali::Integration
+{
+/**
+ * @brief Generates tag 'legacy-prefix-end' with end position of
+ * prefix text to make shader code parsing easier.
+ *
+ * @SINCE_2_3.43
+ * @return Generated string with tag.
+ */
+DALI_CORE_API std::string GenerateTaggedShaderPrefix(const std::string& shaderPrefix);
+
+} // namespace Dali::Integration
+
+#endif // DALI_SHADER_INTEG_H
index 1aafb5861ef5d063fa9ac1301576ae2498381a03..9725a85ab7f0ec033c72044f88779e917f039017 100644 (file)
@@ -366,6 +366,13 @@ void Core::RelayoutAndFlush(SceneContainer& scenes)
     scene->RebuildDepthTree();
   }
 
+  // process events in all scenes
+  for(auto scene : scenes)
+  {
+    auto& renderTaskList = scene->GetRenderTaskList();
+    renderTaskList.ReorderTasks(scene->GetLayerList());
+  }
+
   // Flush any queued messages for the update-thread
   const bool messagesToProcess = mUpdateManager->FlushQueue();
 
@@ -492,9 +499,8 @@ void Core::RunProcessors()
 {
   if(mProcessorsOnce[mProcessorOnceIndex].Count() != 0)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
-      oss << "[" << mProcessorOnceIndex << ":" << mProcessorsOnce[mProcessorOnceIndex].Count() << "]";
-    });
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+                                            { oss << "[" << mProcessorOnceIndex << ":" << mProcessorsOnce[mProcessorOnceIndex].Count() << "]"; });
 
     // Swap processor index.
     uint32_t currentIndex = mProcessorOnceIndex;
@@ -530,21 +536,20 @@ void Core::RunProcessors()
     // Clear once processor.
     mProcessorsOnce[currentIndex].Clear();
 
-    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
+    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+                                          {
       oss << "[" << currentIndex;
       if(mProcessorUnregistered)
       {
         oss << ", processor changed";
       }
-      oss << "]";
-    });
+      oss << "]"; });
   }
 
   if(mProcessors.Count() != 0)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss) {
-      oss << "[" << mProcessors.Count() << "]";
-    });
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss)
+                                            { oss << "[" << mProcessors.Count() << "]"; });
 
     // Copy processor pointers to prevent changes to vector affecting loop iterator.
     Dali::Vector<Integration::Processor*> processors(mProcessors);
@@ -558,13 +563,11 @@ void Core::RunProcessors()
       {
         if(!mProcessorUnregistered)
         {
-          DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
-            oss << "[" << processor->GetProcessorName() << "]";
-          });
+          DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+                                                  { oss << "[" << processor->GetProcessorName() << "]"; });
           processor->Process(false);
-          DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
-            oss << "[" << processor->GetProcessorName() << "]";
-          });
+          DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+                                                { oss << "[" << processor->GetProcessorName() << "]"; });
         }
         else
         {
@@ -573,25 +576,23 @@ void Core::RunProcessors()
           auto iter = std::find(mProcessors.Begin(), mProcessors.End(), processor);
           if(iter != mProcessors.End())
           {
-            DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
-              oss << "[" << processor->GetProcessorName() << "]";
-            });
+            DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+                                                    { oss << "[" << processor->GetProcessorName() << "]"; });
             processor->Process(false);
-            DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
-              oss << "[" << processor->GetProcessorName() << "]";
-            });
+            DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+                                                  { oss << "[" << processor->GetProcessorName() << "]"; });
           }
         }
       }
     }
-    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss) {
+    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss)
+                                          {
       oss << "[" << mProcessors.Count();
       if(mProcessorUnregistered)
       {
         oss << ", processor changed";
       }
-      oss << "]";
-    });
+      oss << "]"; });
   }
 }
 
@@ -599,9 +600,8 @@ void Core::RunPostProcessors()
 {
   if(mPostProcessorsOnce[mPostProcessorOnceIndex].Count() != 0)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
-      oss << "[" << mPostProcessorOnceIndex << ":" << mPostProcessorsOnce[mPostProcessorOnceIndex].Count() << "]";
-    });
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+                                            { oss << "[" << mPostProcessorOnceIndex << ":" << mPostProcessorsOnce[mPostProcessorOnceIndex].Count() << "]"; });
 
     // Swap processor index.
     uint32_t currentIndex = mPostProcessorOnceIndex;
@@ -637,21 +637,20 @@ void Core::RunPostProcessors()
     // Clear once processor.
     mPostProcessorsOnce[currentIndex].Clear();
 
-    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
+    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+                                          {
       oss << "[" << currentIndex;
       if(mPostProcessorUnregistered)
       {
         oss << ", processor changed";
       }
-      oss << "]";
-    });
+      oss << "]"; });
   }
 
   if(mPostProcessors.Count() != 0)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss) {
-      oss << "[" << mPostProcessors.Count() << "]";
-    });
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss)
+                                            { oss << "[" << mPostProcessors.Count() << "]"; });
 
     // Copy processor pointers to prevent changes to vector affecting loop iterator.
     Dali::Vector<Integration::Processor*> processors(mPostProcessors);
@@ -665,13 +664,11 @@ void Core::RunPostProcessors()
       {
         if(!mPostProcessorUnregistered)
         {
-          DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
-            oss << "[" << processor->GetProcessorName() << "]";
-          });
+          DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+                                                  { oss << "[" << processor->GetProcessorName() << "]"; });
           processor->Process(true);
-          DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
-            oss << "[" << processor->GetProcessorName() << "]";
-          });
+          DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+                                                { oss << "[" << processor->GetProcessorName() << "]"; });
         }
         else
         {
@@ -680,26 +677,24 @@ void Core::RunPostProcessors()
           auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), processor);
           if(iter != mPostProcessors.End())
           {
-            DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
-              oss << "[" << processor->GetProcessorName() << "]";
-            });
+            DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+                                                    { oss << "[" << processor->GetProcessorName() << "]"; });
             processor->Process(true);
-            DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
-              oss << "[" << processor->GetProcessorName() << "]";
-            });
+            DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+                                                  { oss << "[" << processor->GetProcessorName() << "]"; });
           }
         }
       }
     }
 
-    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss) {
+    DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss)
+                                          {
       oss << "[" << mPostProcessors.Count();
       if(mPostProcessorUnregistered)
       {
         oss << ", processor changed";
       }
-      oss << "]";
-    });
+      oss << "]"; });
   }
 }
 
index 3a3b12e2576c9a2d20b9bf9950a7b6cd8f36b0bf..a92db2afde3d3464eb64e6694a5a780b972be292 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,8 +57,8 @@ struct ImageAttributes::ImageAttributesImpl
 
   uint16_t    width;                      ///< image width in pixels
   uint16_t    height;                     ///< image height in pixels
-  ScalingMode scaling : 3;                ///< scaling option, ShrinkToFit is default
-  FilterMode  filtering : 4;              ///< filtering option. Box is the default
+  ScalingMode scaling : 4;                ///< scaling option, ShrinkToFit is default
+  FilterMode  filtering : 5;              ///< filtering option. Box is the default
   bool        mOrientationCorrection : 1; ///< If true, image pixels are reordered according to orientation metadata on load.
 };
 
index c35b7b184145ba3009cc041d9721a3b63b223a62..88e77414d876519f4c4c360c7398af913a4a78c1 100644 (file)
@@ -1111,6 +1111,28 @@ DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
   return mParentImpl.ChildOrderChangedSignal();
 }
 
+void Actor::GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward)
+{
+}
+
+void Actor::SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType)
+{
+  mOffScreenRenderableType = offScreenRenderableType;
+}
+
+OffScreenRenderable::Type Actor::GetOffScreenRenderableType() const
+{
+  return mOffScreenRenderableType;
+}
+
+void Actor::RequestRenderTaskReorder()
+{
+  if(mScene && GetOffScreenRenderableType() != OffScreenRenderable::Type::NONE)
+  {
+    mScene->GetRenderTaskList().RequestReorder();
+  }
+}
+
 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
 : Object(&node),
   mParentImpl(*this),
@@ -1170,7 +1192,8 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mColorMode(Node::DEFAULT_COLOR_MODE),
   mClippingMode(ClippingMode::DISABLED),
   mHoverState(PointState::FINISHED),
-  mBlendEquation(DevelBlendEquation::ADD)
+  mBlendEquation(DevelBlendEquation::ADD),
+  mOffScreenRenderableType(OffScreenRenderable::Type::NONE)
 {
 }
 
index f9aa9708c8cf5a50529730b45975d3069d2aacfc..99dcf9c7ec18ec89394b281aba4994978dcc503b 100644 (file)
 #include <string>
 
 // INTERNAL INCLUDES
-#include <dali/public-api/actors/actor.h>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/events/gesture.h>
-#include <dali/public-api/math/viewport.h>
-#include <dali/public-api/object/ref-object.h>
-#include <dali/public-api/size-negotiation/relayout-container.h>
-
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
-
 #include <dali/integration-api/events/touch-event-integ.h>
-
 #include <dali/internal/common/const-string.h>
 #include <dali/internal/common/internal-constants.h>
 #include <dali/internal/common/memory-pool-object-allocator.h>
 #include <dali/internal/event/common/object-impl.h>
 #include <dali/internal/event/common/stage-def.h>
 #include <dali/internal/update/nodes/node-declarations.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/events/gesture.h>
+#include <dali/public-api/math/viewport.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
 
 namespace Dali
 {
@@ -1577,6 +1575,46 @@ public:
   {
   }
 
+public:
+  // For Internal RenderTask Ordering
+
+  /**
+   * @brief Retrieves the off-screen RenderTasks associated with the Actor.
+   * This method returns the internal RenderTasks held by the Actor. This tasks are
+   * used for off-screen rendering, and the system will assign order index to each
+   * tasks based on the render order.
+   *
+   * Actor with a non-NONE OffScreenRenderableType should override this method to
+   * provide their render tasks.
+   *
+   * @param[out] tasks A list of RenderTasks to be populated with the Actor's forward
+   * or backward off-screen RenderTask.
+   * @param[in] isForward Indicates whether to retrieve forward (true) or backward (false)
+   * RenderTasks.
+   */
+  virtual void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward);
+
+  /**
+   * @brief Sets OffScreenRenderableType of this Actor.
+   * This method is called by child class to set type itself.
+   *
+   * @param[in] offScreenRenderableType OffScreenRenderableType for this Actor.
+   * It could be one of NONE, FORWARD, BACKWARD, and BOTH.
+   */
+  void SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType);
+
+  /**
+   * @brief Retrieves OffScreenRenderableType of this Actor.
+   *
+   * @return OffScreenRenderableType for this Actor.
+   */
+  OffScreenRenderable::Type GetOffScreenRenderableType() const;
+
+  /**
+   * @brief Requests RenderTask reordering when the offscreen properties of this Actor are changed.
+   */
+  void RequestRenderTaskReorder();
+
 protected:
   enum DerivedType
   {
@@ -2027,6 +2065,9 @@ protected:
 private:
   static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
 
+  // OffScreenRenderable
+  OffScreenRenderable::Type mOffScreenRenderableType;
+
   struct PropertyHandler;
   struct SiblingHandler;
 
index 9ccabff830496a728f0d4e93a06732d8d9e42686..31def8cabbc9ef7f3faafeebb50b936639817bad 100644 (file)
@@ -451,6 +451,8 @@ void ActorParentImpl::RecursiveConnectToScene(ActorContainer& connectionList, ui
   mOwner.mLayer3DParentsCount = static_cast<uint16_t>(layer3DParentsCount); // overflow ignored, not expected in practice
   mOwner.ConnectToSceneGraph();
 
+  mOwner.RequestRenderTaskReorder();
+
   // Notification for internal derived classes
   mOwner.OnSceneConnectionInternal();
 
index a70d8845468c4e5db4f8b4b06899bf5ddfae3c79..969cb6955607223ec9022aa0e5eeb2026863d7c6 100644 (file)
@@ -128,6 +128,11 @@ private:
     mImpl->OnSizeAnimation(animationHandle, targetSize);
   }
 
+  void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward)
+  {
+    mImpl->GetOffScreenRenderTasks(tasks, isForward);
+  }
+
   /**
    * @copydoc Internal::Actor::OnRelayout
    */
index 0ae6fdafffcd3ccea091b89cc03d4f5a3ddaf011..5133ea2c668675902c5d3d935a45e8ffd41f3554 100644 (file)
@@ -138,6 +138,7 @@ void Scene::Initialize(Size size, int32_t windowOrientation, int32_t screenOrien
 
   // Create the default render-task and ensure clear is enabled on it to show the background color
   RenderTaskPtr renderTask = mRenderTaskList->CreateTask(mRootLayer.Get(), mDefaultCamera.Get());
+  renderTask->SetOrderIndex(INT32_MIN);
   renderTask->SetClearEnabled(true);
 
   // Create scene graph object
index 678ae49710d1d5d89b682dffaad9bb11f2664bfa..f3f54fd7ef86a26f16b4585d66d031b319abc3e8 100644 (file)
@@ -33,6 +33,8 @@ namespace
 {
 const char* VERSION_SEPARATOR = "-";
 const char* SHADER_SUFFIX     = ".dali-bin";
+
+constexpr uint32_t MAXIMUM_STRING_SHADER_DATA_CACHE_CLEAN_THRESHOLD = 128u;
 } // namespace
 
 namespace Dali
@@ -188,6 +190,11 @@ void ShaderFactory::MemoryCacheInsert(ShaderData& shaderData, const bool isBinar
   }
   else
   {
+    if(DALI_UNLIKELY(mTotalStringCachedShadersCount >= MAXIMUM_STRING_SHADER_DATA_CACHE_CLEAN_THRESHOLD))
+    {
+      // Reset string cache, to avoid memory leak problem.
+      ResetStringShaderData();
+    }
     auto& cacheList = mShaderStringCache[shaderHash]; ///< Get or create a new cache list.
 
     // Ignore shaderdata with string if it already exists:
@@ -202,6 +209,8 @@ void ShaderFactory::MemoryCacheInsert(ShaderData& shaderData, const bool isBinar
     }
     shaderData.Reference();
     cacheList.PushBack(&shaderData);
+
+    ++mTotalStringCachedShadersCount;
     DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "CACHED NON-BINARY SHADER FOR HASH: %u, HINT: %d, TAG: %u\n", shaderHash, static_cast<int>(shaderData.GetHints()), shaderData.GetRenderPassTag());
   }
 }
@@ -222,6 +231,8 @@ void ShaderFactory::RemoveStringShaderData(ShaderData& shaderData)
         // Reduce reference before erase
         (*iter)->Unreference();
         cacheList.Erase(iter);
+
+        --mTotalStringCachedShadersCount;
         break;
       }
     }
@@ -232,6 +243,25 @@ void ShaderFactory::RemoveStringShaderData(ShaderData& shaderData)
   }
 }
 
+void ShaderFactory::ResetStringShaderData()
+{
+  DALI_LOG_RELEASE_INFO("Trigger StringShaderData GC. shader : [%u]\n", mTotalStringCachedShadersCount);
+  for(auto&& iter : mShaderStringCache)
+  {
+    auto& cacheList = iter.second;
+    for(auto&& shaderData : cacheList)
+    {
+      shaderData->Unreference();
+    }
+  }
+
+  // Reset cache after unreference.
+  mShaderStringCache.clear();
+
+  mTotalStringCachedShadersCount = 0u;
+  DALI_LOG_RELEASE_INFO("StringShaderData GC done\n");
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 0662c31c78e5ce3b1ff4dad9930259bc70f082c2..afadccd8fcb9cbb84a1253f9f904c91e326e9000 100644 (file)
@@ -90,6 +90,11 @@ private:
    */
   void RemoveStringShaderData(Internal::ShaderData& shaderData);
 
+  /**
+   * @brief Remove all the string shader data from the cache.
+   */
+  void ResetStringShaderData();
+
   // Undefined
   ShaderFactory(const ShaderFactory&) = delete;
 
@@ -102,6 +107,8 @@ private:
   ShaderCacheContainer mShaderBinaryCache; ///< Cache of pre-compiled shaders.
   ShaderCacheContainer mShaderStringCache; ///< Cache of non-pre-compiled shaders. (TODO : Could we clean up this cache by user management?)
 
+  uint32_t mTotalStringCachedShadersCount{0u}; ///< Total number of cached shaders that are not pre-compiled.
+
 }; // class ShaderFactory
 
 inline MessageBase* ShaderCompiledMessage(ShaderSaver& factory, Internal::ShaderDataPtr shaderData)
index 99077611591f43ee505e76c9cbd40dfee17cd0d9..09db52ebb59a2db0c51838de535885bb6907e293 100644 (file)
@@ -42,6 +42,11 @@ namespace Dali
 {
 namespace Internal
 {
+
+typedef std::vector<Actor*>                             OffScreenRenderableContainer;
+typedef std::pair<Actor*, OffScreenRenderableContainer> ForwardOffScreenRenderableSubTree;
+typedef std::vector<ForwardOffScreenRenderableSubTree>  OffScreenRenderableData;
+
 namespace
 {
 static constexpr uint32_t ORDER_INDEX_OVERLAY_RENDER_TASK = INT32_MAX;
@@ -187,6 +192,172 @@ void RenderTaskList::SortTasks()
   mIsRequestedToSortTask = false;
 }
 
+bool IsWithinSourceActors(const Actor& sourceActor, Actor& actor)
+{
+  bool isInside = false;
+  Actor* currentActor = &actor;
+  while(currentActor)
+  {
+    if(&sourceActor == currentActor)
+    {
+      isInside = true;
+      break;
+    }
+
+    if(currentActor->GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+    {
+      isInside = false;
+      break;
+    }
+    currentActor = currentActor->GetParent();
+  }
+  return isInside;
+}
+
+void FindOffScreenRenderableWithinSubTree(Actor& rootActor, Actor& actor, uint32_t subTreeIndex, std::vector<Actor*>& onScreenSources, OffScreenRenderableData& renderableData, std::vector<bool>& traverseFinished)
+{
+  if(&actor != renderableData[subTreeIndex].first)
+  {
+
+    // New BACKWARD OffScreen Renderable
+    if(actor.GetOffScreenRenderableType() & OffScreenRenderable::Type::BACKWARD)
+    {
+      renderableData[subTreeIndex].second.push_back(&actor);
+    }
+
+    // New FORWARD OffScreen Renderable. It makes new subTree.
+    if(actor.GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+    {
+      ForwardOffScreenRenderableSubTree newSubTree;
+      newSubTree.first = &actor;
+      renderableData.push_back(newSubTree);
+      traverseFinished.push_back(false);
+      return;
+    }
+
+    // OnScreen Source and its child will be traversed by next loop.
+    if(std::find(onScreenSources.begin(), onScreenSources.end(), &actor) != onScreenSources.end())
+    {
+      return;
+    }
+
+    if(rootActor.GetId() != actor.GetId() && actor.GetLayer().GetProperty<int32_t>(Dali::Actor::Property::ID) == static_cast<int32_t>(actor.GetId()))
+    {
+      return;
+    }
+  }
+
+  uint32_t childCount = actor.GetChildCount();
+  for(uint32_t i = 0; i < childCount; ++i)
+  {
+    auto child = actor.GetChildAt(i);
+    FindOffScreenRenderableWithinSubTree(rootActor, *(child.Get()), subTreeIndex, onScreenSources, renderableData, traverseFinished);
+  }
+}
+
+void RenderTaskList::ReorderTasks(Dali::Internal::LayerList& layerList)
+{
+  if(mIsRequestedToReorderTask)
+  {
+    std::vector<bool>       traverseFinished;
+    OffScreenRenderableData renderableData;
+    uint32_t                layerCount = layerList.GetLayerCount();
+    uint32_t                taskCount  = GetTaskCount();
+    std::vector<Actor*>     onScreenSources;
+    for(uint32_t i = 0; i < taskCount; ++i)
+    {
+      auto renderTask = GetTask(i);
+      if(!renderTask->GetFrameBuffer())
+      {
+        onScreenSources.push_back(renderTask->GetSourceActor());
+      }
+    }
+
+    for(uint32_t i = 0; i < taskCount; ++i)
+    {
+      auto renderTask = GetTask(i);
+      if(renderTask->GetFrameBuffer())
+      {
+        continue;
+      }
+
+      auto*                             sourceActor = renderTask->GetSourceActor();
+      ForwardOffScreenRenderableSubTree subTree;
+      subTree.first = sourceActor;
+      renderableData.push_back(subTree);
+      traverseFinished.push_back(false);
+
+      uint32_t currentSubTreeIndex = 0;
+      Actor*   root                = subTree.first;
+      while(root)
+      {
+        Dali::Layer    sourceLayer      = root->GetLayer();
+        const uint32_t sourceLayerDepth = sourceLayer.GetProperty<int32_t>(Dali::Layer::Property::DEPTH);
+        for(uint32_t currentLayerIndex = 0; currentLayerIndex < layerCount; ++currentLayerIndex)
+        {
+          auto*                  layer     = layerList.GetLayer(currentLayerIndex);
+          Dali::Internal::Actor* rootActor = nullptr;
+          if(sourceLayerDepth == currentLayerIndex)
+          {
+            rootActor = root;
+          }
+          else
+          {
+            if(!IsWithinSourceActors(*root, *layer))
+            {
+              continue;
+            }
+            rootActor = layer;
+          }
+          FindOffScreenRenderableWithinSubTree(*rootActor, *rootActor, currentSubTreeIndex, onScreenSources, renderableData, traverseFinished);
+        }
+
+        traverseFinished[currentSubTreeIndex] = true;
+
+        root = nullptr;
+        for(currentSubTreeIndex = 0; currentSubTreeIndex < traverseFinished.size(); ++currentSubTreeIndex)
+        {
+          if(!traverseFinished[currentSubTreeIndex])
+          {
+            root = renderableData[currentSubTreeIndex].first;
+            break;
+          }
+        }
+      }
+    }
+
+    // Default Task should have the lowest OrderIndex number.
+    int32_t  orderIndex   = GetTask(0u)->GetOrderIndex();
+    uint32_t subTreeCount = renderableData.size();
+    for(uint32_t i = subTreeCount - 1; i < subTreeCount; --i)
+    {
+      auto subTree = renderableData[i];
+      for(auto&& actor : subTree.second)
+      {
+        std::vector<Dali::RenderTask> tasks;
+        actor->GetOffScreenRenderTasks(tasks, false);
+        for(auto&& task : tasks)
+        {
+          GetImplementation(task).SetOrderIndex(orderIndex++);
+        }
+      }
+
+      if(subTree.first && subTree.first->GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+      {
+        std::vector<Dali::RenderTask> tasks;
+        subTree.first->GetOffScreenRenderTasks(tasks, true);
+        for(auto&& task : tasks)
+        {
+          GetImplementation(task).SetOrderIndex(orderIndex++);
+        }
+      }
+    }
+
+    SortTasks();
+  }
+  mIsRequestedToReorderTask = false;
+}
+
 RenderTaskList::RenderTaskList()
 : mEventThreadServices(EventThreadServices::Get()),
   mDefaults(*Stage::GetCurrent()),
index 8fce92f10776380eb5e795186092874711a04c8f..af02533816b248870e511362f52336665c921e29 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 
+#include <dali/internal/event/actors/layer-list.h>
 #include <dali/internal/event/common/complete-notification-interface.h>
 #include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
 #include <dali/internal/event/events/actor-observer.h>
@@ -162,6 +163,21 @@ public:
    */
   void SortTasks();
 
+  /**
+   * @brief Requests to reorder the RenderTasks of this RenderTaskList.
+   */
+  void RequestReorder()
+  {
+    mIsRequestedToReorderTask = true;
+  }
+
+  /**
+   * @brief Reorder RenderTasks along the priority of OffScreenRenderableType of each Actor.
+   *
+   * @param[in] layerList layerList that used for tasks reordering.
+   */
+  void ReorderTasks(Dali::Internal::LayerList& layerList);
+
   /**
    * Provide notification signals for a "Finished" render task.
    * This method should be called in the event-thread
@@ -215,6 +231,7 @@ private:
   RenderTaskPtr       mOverlayRenderTask{nullptr};
 
   bool mIsRequestedToSortTask{false};
+  bool mIsRequestedToReorderTask{false};
 };
 
 } // namespace Internal
index 44a12cc222a8ea1c824accc67c0bf97cc04fdcaa..fb32ee0d8b372dae318ff74f60cfb1a583bc5f9d 100644 (file)
@@ -348,13 +348,13 @@ std::string Shader::GetShaderVersionPrefix()
 std::string Shader::GetVertexShaderPrefix()
 {
   Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
-  return tls.GetVertexShaderPrefix();
+  return GenerateTaggedShaderPrefix(tls.GetVertexShaderPrefix());
 }
 
 std::string Shader::GetFragmentShaderPrefix()
 {
   Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
-  return tls.GetFragmentShaderPrefix();
+  return GenerateTaggedShaderPrefix(tls.GetFragmentShaderPrefix());
 }
 
 std::string Shader::GenerateTaggedShaderPrefix(const std::string& shaderPrefix)
index 0f597d1f7633848854710871940e78d24cbf3492..1b46fc234d7d947b1cee92e6092d6c47878f7e0c 100644 (file)
@@ -146,7 +146,7 @@ public:
   /**
    * Generates tag 'legacy-prefix-end' with end position of
    * prefix text to make shader code parsing easier.
-   * Function is public to be testable
+   * Function is public to be testable and integration api.
    */
   static std::string GenerateTaggedShaderPrefix(const std::string& shaderPrefix);
 };
index fd56538e772b61a76df0737b171e0db5715fa446..7f067c17716aa28fd033ac4f22bb1c7b57294add 100644 (file)
@@ -40,6 +40,7 @@ namespace Render
 {
 namespace
 {
+
 struct GraphicsDepthCompareOp
 {
   constexpr explicit GraphicsDepthCompareOp(DepthFunction::Type compareOp)
@@ -147,7 +148,7 @@ struct GraphicsStencilOp
 
 inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, ClippingBox clippingBox, int orientation)
 {
-  Graphics::Viewport viewport{static_cast<float>(clippingBox.x), static_cast<float>(clippingBox.y), static_cast<float>(clippingBox.width), static_cast<float>(clippingBox.height), 0.0f, 0.0f};
+  Graphics::Viewport viewport{static_cast<float>(clippingBox.x), static_cast<float>(clippingBox.y), static_cast<float>(clippingBox.width), static_cast<float>(clippingBox.height), 0.0f, 1.0f};
 
   if(orientation == 90 || orientation == 270)
   {
@@ -169,6 +170,8 @@ inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, C
     viewport.x = sceneSize.GetX() - (clippingBox.x + clippingBox.width);
     viewport.y = sceneSize.GetY() - (clippingBox.y + clippingBox.height);
   }
+  viewport.minDepth = 0;
+  viewport.maxDepth = 1;
   return viewport;
 }
 
@@ -630,9 +633,9 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
 
   // Add root clipping rect (set manually for Render function by partial update for example)
   // on the bottom of the stack
+  Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
   if(!rootClippingRect.IsEmpty())
   {
-    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
     secondaryCommandBuffer.SetScissorTestEnable(true);
     secondaryCommandBuffer.SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport));
     mScissorStack.push_back(rootClippingRect);
@@ -641,12 +644,13 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   else if(!renderList.IsClipping())
   {
     secondaryCommandBuffer.SetScissorTestEnable(false);
+    //@todo Vk requires a scissor to be set, as we have turned on dynamic state scissor in the pipelines.
+    secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(mViewportRectangle, orientation, graphicsViewport));
     mScissorStack.push_back(mViewportRectangle);
   }
 
   if(renderList.IsClipping())
   {
-    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
     secondaryCommandBuffer.SetScissorTestEnable(true);
     const ClippingBox& layerScissorBox = renderList.GetClippingBox();
     secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport));
@@ -657,6 +661,13 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   // Prepare Render::Renderer Render for this secondary command buffer.
   Renderer::PrepareCommandBuffer();
 
+  // Modify by the clip matrix if necessary (transforms from GL clip space to alternative clip space)
+  Matrix clippedProjectionMatrix(projectionMatrix);
+  if(mGraphicsController.HasClipMatrix())
+  {
+    Matrix::Multiply(clippedProjectionMatrix, projectionMatrix, mGraphicsController.GetClipMatrix());
+  }
+
   // Loop through all RenderItems in the RenderList, set up any prerequisites to render them, then perform the render.
   for(uint32_t index = 0u; index < count; ++index)
   {
@@ -708,7 +719,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
         for(auto queue = 0u; queue < MAX_QUEUE; ++queue)
         {
           // Render the item. It will write into the command buffer everything it has to render
-          item.mRenderer->Render(secondaryCommandBuffer, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mScale, item.mSize, !item.mIsOpaque, instruction, renderTarget, queue);
+          item.mRenderer->Render(secondaryCommandBuffer, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, clippedProjectionMatrix, item.mScale, item.mSize, !item.mIsOpaque, instruction, renderTarget, queue);
         }
       }
     }
index 42b8652e8a63f9801739fce8e711e6473c4b3858..5aff37e3d7d8a9da0aeaa3edc483c56aca853293 100644 (file)
@@ -1040,6 +1040,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     {
       iter->type           = Graphics::ResourceType::PROGRAM;
       iter->programBinding = &item.second;
+      ++iter;
     }
   }
 
@@ -1256,10 +1257,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
       scissorArea,
       currentClearValues);
 
-    mainCommandBuffer->SetViewport({float(viewportRect.x),
-                                    float(viewportRect.y),
-                                    float(viewportRect.width),
-                                    float(viewportRect.height)});
+    // Note, don't set the viewport/scissor on the primary command buffer.
 
     mImpl->renderAlgorithms.ProcessRenderInstruction(
       instruction,
@@ -1287,7 +1285,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
   if(targetsToPresent.size() > 0u)
   {
-    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) { oss << "[" << targetsToPresent.size() << "]"; });
+    DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss)
+                                            { oss << "[" << targetsToPresent.size() << "]"; });
   }
 
   // Flush UBOs
index 14c98210f1c13d8796b815378578dea9492d66cc..3edcfdfa0152c25bcf1eed3184995247d88c2563 100644 (file)
@@ -188,6 +188,21 @@ enum Type
 
 } // namespace LayoutDirection
 
+/**
+ * @brief Enumeration for the OffScreenRenderable of the Actor
+ * @SINCE_2_3.43
+ */
+namespace OffScreenRenderable
+{
+enum Type
+{
+  NONE     = 0,                  // The Actor has no OffScreenRenderables. @SINCE_2_3.43
+  FORWARD  = 1,                  // The Actor has RenderTasks those need reorder. And the Tasks will draw Actors those placed in front of the Actor. @SINCE_2_3.43
+  BACKWARD = 2,                  // The Actor has RenderTasks those need reorder, And the Tasks will draw Actors those placed behinde of the Actor. @SINCE_2_3.43
+  BOTH     = FORWARD | BACKWARD, // The Actor has RenderTasks for the both of FORWARD and BACKWARD. @SINCE_2_3.43
+};
+} // namespace OffScreenRenderables
+
 /**
  * @}
  */
index ad000b8ec95495ab747794a15898d6cd0a62c86d..12a1d1f0656e2a28cb9c79afe60b53f7989af718 100644 (file)
@@ -33,6 +33,21 @@ void CustomActorImpl::OnPropertySet(Property::Index index, const Property::Value
 {
 }
 
+void CustomActorImpl::SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType)
+{
+  mOwner->SetOffScreenRenderableType(offScreenRenderableType);
+}
+
+OffScreenRenderable::Type CustomActorImpl::GetOffScreenRenderableType()
+{
+  return mOwner->GetOffScreenRenderableType();
+}
+
+void CustomActorImpl::RequestRenderTaskReorder()
+{
+  mOwner->RequestRenderTaskReorder();
+}
+
 CustomActorImpl::CustomActorImpl(ActorFlags flags)
 : mOwner(nullptr),
   mFlags(flags)
index cc1a53e22e23e04a5cd010ea92f5276cfcc28de5..21af81865ea3981687d6c423e9b5c53b8e9a6fd2 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/math/compile-time-math.h>
 #include <dali/public-api/object/property.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/render-tasks/render-task.h>
 
 namespace Dali
 {
@@ -39,7 +42,6 @@ namespace Internal DALI_INTERNAL
 class CustomActor;
 }
 
-class Actor;
 class Animation;
 class CustomActor;
 class CustomActorImpl;
@@ -172,6 +174,47 @@ public:
    */
   virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize) = 0;
 
+  /**
+   * @brief Retrieves the off-screen RenderTasks associated with the Actor.
+   * This method returns the internal RenderTasks held by the Actor. This tasks are
+   * used for off-screen rendering, and the system will assign order index to each
+   * tasks based on the render order.
+   *
+   * Actor with a non-NONE OffScreenRenderableType should override this method to
+   * provide their render tasks.
+   *
+   * @SINCE_2_3.43
+   * @param[out] tasks A list of RenderTasks to be populated with the Actor's forward
+   * or backward off-screen RenderTask.
+   * @param[in] isForward Indicates whether to retrieve forward (true) or backward (false)
+   * RenderTasks.
+   */
+  virtual void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) = 0;
+
+  /**
+   * @brief Sets OffScreenRenderableType of this Actor.
+   * This method is called by child class to set type itself.
+   *
+   * @SINCE_2_3.43
+   * @param[in] offScreenRenderableType OffScreenRenderableType for this Actor.
+   * It could be one of NONE, FORWARD, BACKWARD, and BOTH.
+   */
+  void SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType);
+
+  /**
+   * @brief Retrieves OffScreenRenderableType of this Actor.
+   *
+   * @SINCE_2_3.43
+   * @return OffScreenRenderableType for this Actor.
+   */
+  OffScreenRenderable::Type GetOffScreenRenderableType();
+
+  /**
+   * @brief Requests RenderTask reordering when the offscreen properties of this Actor are changed.
+   * @SINCE_2_3.43
+   */
+  void RequestRenderTaskReorder();
+
   /**
    * @brief Called after the size negotiation has been finished for this control.
    *
index 8743c3374aedbfaba239d7c2b997c52d94e7a60f..aa9e1ccbe790effb9a0837ffdf6879cc8bb6b925 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const uint32_t    CORE_MAJOR_VERSION = 2;
 const uint32_t    CORE_MINOR_VERSION = 3;
-const uint32_t    CORE_MICRO_VERSION = 42;
+const uint32_t    CORE_MICRO_VERSION = 44;
 const char* const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 8642976cfd4d91b1d207b78aca5a1a09e0e5fab0..6af7cba54d31438adcc7bcdae3c661133704b71f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_IMAGE_OPERATIONS_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -92,9 +92,9 @@ const Type DEFAULT = SHRINK_TO_FIT;
 namespace SamplingMode
 {
 /**
  * @brief Enumeration for SamplingMode type.
  * @SINCE_1_0.0
  */
+ * @brief Enumeration for SamplingMode type.
+ * @SINCE_1_0.0
+ */
 enum Type
 {
   BOX,              ///< Iteratively box filter to generate an image of 1/2, 1/4,
@@ -119,9 +119,15 @@ enum Type
                     ///  is enabled, the borders of the image may be trimmed to
                     ///  match the aspect ratio of the desired dimensions.
                     ///  @SINCE_1_0.0
-  DONT_CARE         ///< For caching algorithms where a client strongly prefers a
+  DONT_CARE,        ///< For caching algorithms where a client strongly prefers a
                     ///  cache-hit to reuse a cached image.
                     ///  @SINCE_1_0.0
+  LANCZOS,          ///< Use filter with Lanczos resample algorithm.
+                    ///  @SINCE_2_3.43
+  BOX_THEN_LANCZOS, ///< Iteratively box filter to generate an image of 1/2, 1/4,
+                    ///  1/8 etc width and height and approximately the desired
+                    ///  size, then apply Lanczos resample algorithm.
+                    ///  @SINCE_2_3.43
 };
 const Type DEFAULT = BOX;
 } // namespace SamplingMode
index bd0cf0420f8f5bcd7f9a678fead8c203ff9e531b..d78ecc348e958ffa096e8db3f5e71b6f5c65236c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2
 Summary:    DALi 3D Engine
-Version:    2.3.42
+Version:    2.3.44
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT