Automatic RenderTask Ordering 00/314200/27
authorSeungho Baek <sbsh.baek@samsung.com>
Mon, 8 Jul 2024 13:09:54 +0000 (22:09 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Wed, 25 Sep 2024 07:03:55 +0000 (16:03 +0900)
Change-Id: Icb2f3857756169d6bd6b5691112b6b5b9f93b7e6
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
16 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-custom-actor.h
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
dali/internal/common/core-impl.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/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/public-api/actors/actor-enumerations.h
dali/public-api/actors/custom-actor-impl.cpp
dali/public-api/actors/custom-actor-impl.h

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 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 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 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 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 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..5ffa84ffb742c1af879d2e15bfbd45d52bca3f0d 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/actors/actor.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 +41,6 @@ namespace Internal DALI_INTERNAL
 class CustomActor;
 }
 
-class Actor;
 class Animation;
 class CustomActor;
 class CustomActorImpl;
@@ -172,6 +173,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.
    *