[Tizen] Make an Actor be exclusive source actor for multiple RenderTask 06/298706/1 accepted/tizen/7.0/unified/20230915.095415
authorseungho baek <sbsh.baek@samsung.com>
Thu, 24 Aug 2023 08:12:14 +0000 (17:12 +0900)
committerseungho baek <sbsh.baek@samsung.com>
Tue, 12 Sep 2023 13:05:59 +0000 (22:05 +0900)
Change-Id: Id0e6db5a514c3fc2d4c53bb3e5da83ea9f27f0c4
Signed-off-by: seungho baek <sbsh.baek@samsung.com>
automated-tests/src/dali/utc-Dali-RenderTask.cpp
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/internal/update/render-tasks/scene-graph-render-task.cpp

index 04d092a..ffbd1eb 100644 (file)
@@ -894,6 +894,68 @@ int UtcDaliRenderTaskSetExclusive02(void)
   END_TEST;
 }
 
+int UtcDaliRenderTaskSetExclusive03(void)
+{
+  TestApplication application;
+
+  tet_infoline("Testing RenderTask::SetExclusive() Check that changing from exclusive to not-exclusive works");
+
+  std::vector<GLuint> ids;
+  ids.push_back(8); // 8 = actor1
+  application.GetGlAbstraction().SetNextTextureIds(ids);
+
+  Texture img1   = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Actor   actor1 = CreateRenderableActor(img1);
+  actor1.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+  application.GetScene().Add(actor1);
+
+  RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+  RenderTask     task     = taskList.CreateTask();
+
+  task.SetSourceActor(actor1);
+  task.SetExclusive(true); // Actor should only render once
+
+  TestGlAbstraction& gl        = application.GetGlAbstraction();
+  TraceCallStack&    drawTrace = gl.GetDrawTrace();
+  drawTrace.Enable(true);
+
+  // Update & Render actor1
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
+
+  // Set task to non-exclusive - actor1 should render twice:
+  drawTrace.Reset();
+
+  RenderTask task2 = taskList.CreateTask();
+  task2.SetSourceActor(actor1);
+  task2.SetExclusive(true); // Actor should only render once
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 2, TEST_LOCATION);
+
+  // Set task to non-exclusive - actor1 should render twice:
+  drawTrace.Reset();
+  task.SetExclusive(false);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
+
+  // Set task to non-exclusive - actor1 should render twice:
+  drawTrace.Reset();
+  task2.SetExclusive(false);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 3, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliRenderTaskSetExclusiveN(void)
 {
   TestApplication application;
index 275229b..3590441 100644 (file)
@@ -45,10 +45,9 @@ namespace //Unnamed namespace
 // Return false if the node or it's parents are exclusive to another render-task.
 bool CheckExclusivity(const Node& node, const RenderTask& task)
 {
-  const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
-  if(exclusiveTo)
+  if(node.IsExclusiveRenderTask(&task))
   {
-    return (exclusiveTo == &task);
+    return true;
   }
 
   const Node* parent = node.GetParent();
@@ -122,8 +121,7 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
   }
 
   // Check whether node is exclusive to a different render-task
-  const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
-  if(exclusiveTo && (exclusiveTo != &renderTask))
+  if(node.GetExclusiveRenderTaskCount() && !node.IsExclusiveRenderTask(&renderTask))
   {
     return keepRendering;
   }
index af5962d..8f9b537 100644 (file)
@@ -89,7 +89,6 @@ Node::Node()
   mClippingSortModifier(0u),
   mId(++mNodeCounter),
   mParent(nullptr),
-  mExclusiveRenderTask(nullptr),
   mChildren(),
   mClippingDepth(0u),
   mScissorDepth(0u),
index 2cb97a3..e5863e0 100644 (file)
@@ -72,6 +72,8 @@ static NodePropertyFlags RenderableUpdateFlags = NodePropertyFlags::TRANSFORM |
 class Node : public PropertyOwner, public NodeDataProvider
 {
 public:
+  using RenderTaskContainer = std::vector<RenderTask*>;
+
   // Defaults
   static const ColorMode DEFAULT_COLOR_MODE;
 
@@ -728,21 +730,53 @@ public:
   }
 
   /**
-   * Mark the node as exclusive to a single RenderTask.
-   * @param[in] renderTask The render-task, or NULL if the Node is not exclusive to a single RenderTask.
+   * Add RenderTask that will exclusively render this node.
+   * @param[in] renderTask The render-task to render this node exclusively.
    */
-  void SetExclusiveRenderTask(RenderTask* renderTask)
+  void AddExclusiveRenderTask(RenderTask* renderTask)
   {
-    mExclusiveRenderTask = renderTask;
+    auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
+    if(found == mExclusiveRenderTasks.end())
+    {
+      mExclusiveRenderTasks.push_back(renderTask);
+    }
   }
 
   /**
-   * Query whether the node is exclusive to a single RenderTask.
-   * @return The render-task, or NULL if the Node is not exclusive to a single RenderTask.
+   * Remove a RenderTask from exclusive render task queue.
+   * The RenderTask cannot render this node if this node is exclusive to other RenderTasks.
+   * @param[in] renderTask The render-task to be removed from exclusive render task queue.
    */
-  RenderTask* GetExclusiveRenderTask() const
+  void RemoveExclusiveRenderTask(RenderTask* renderTask)
   {
-    return mExclusiveRenderTask;
+    auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
+    if(found != mExclusiveRenderTasks.end())
+    {
+      mExclusiveRenderTasks.erase(found);
+    }
+  }
+
+  /**
+   * Retrieves the number of exclusive RenderTask for this node.
+   * @return The number of exclusive RenderTask.
+   */
+  uint32_t GetExclusiveRenderTaskCount()
+  {
+    return mExclusiveRenderTasks.size();
+  }
+
+  /**
+   * Query whether the node is exclusive to the renderTask.
+   * @return true if this node is exclusive to the renderTask.
+   */
+  bool IsExclusiveRenderTask(const RenderTask* renderTask) const
+  {
+    auto found = std::find(mExclusiveRenderTasks.begin(), mExclusiveRenderTasks.end(), renderTask);
+    if(found != mExclusiveRenderTasks.end())
+    {
+      return true;
+    }
+    return false;
   }
 
   /**
@@ -958,8 +992,8 @@ public: // Default properties
 protected:
   static uint32_t mNodeCounter; ///< count of total nodes, used for unique ids
 
-  Node*       mParent;              ///< Pointer to parent node (a child is owned by its parent)
-  RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask
+  Node*               mParent;               ///< Pointer to parent node (a child is owned by its parent)
+  RenderTaskContainer mExclusiveRenderTasks; ///< Nodes can be marked as exclusive to multiple RenderTasks
 
   RendererContainer mRenderer; ///< Container of renderers; not owned
 
index 116c681..2ef2cf6 100644 (file)
@@ -45,7 +45,7 @@ RenderTask::~RenderTask()
     mSourceNode->RemoveObserver(*this);
     if(mExclusive)
     {
-      mSourceNode->SetExclusiveRenderTask(nullptr);
+      mSourceNode->RemoveExclusiveRenderTask(this);
     }
   }
   if(mCameraNode)
@@ -69,10 +69,7 @@ void RenderTask::SetSourceNode(Node* node)
   if(mSourceNode)
   {
     mSourceNode->RemoveObserver(*this);
-    if(this == mSourceNode->GetExclusiveRenderTask())
-    {
-      mSourceNode->SetExclusiveRenderTask(nullptr);
-    }
+    mSourceNode->RemoveExclusiveRenderTask(this);
   }
 
   mSourceNode = node;
@@ -82,7 +79,7 @@ void RenderTask::SetSourceNode(Node* node)
     mSourceNode->AddObserver(*this);
     if(mExclusive)
     {
-      mSourceNode->SetExclusiveRenderTask(this);
+      mSourceNode->AddExclusiveRenderTask(this);
     }
   }
   SetActiveStatus();
@@ -111,11 +108,11 @@ void RenderTask::SetExclusive(bool exclusive)
   {
     if(mExclusive)
     {
-      mSourceNode->SetExclusiveRenderTask(this);
+      mSourceNode->AddExclusiveRenderTask(this);
     }
-    else if(this == mSourceNode->GetExclusiveRenderTask())
+    else
     {
-      mSourceNode->SetExclusiveRenderTask(nullptr);
+      mSourceNode->RemoveExclusiveRenderTask(this);
     }
   }
 }