Add Actor::Ignored to optimize invisible actors in render thread 18/322118/13
authorSeungho Baek <sbsh.baek@samsung.com>
Thu, 3 Apr 2025 12:57:14 +0000 (21:57 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Wed, 28 May 2025 05:24:02 +0000 (14:24 +0900)
Change-Id: I042e90b711e9af80298c7f01213a2aed723d5216
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
15 files changed:
automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/events/gesture-processor.cpp
dali/internal/event/events/hit-test-algorithm-impl.cpp
dali/internal/event/events/hover-event-processor.cpp
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/manager/transform-manager.cpp
dali/internal/update/manager/transform-manager.h
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/actors/actor.cpp
dali/public-api/actors/actor.h

index fb4c85cf66beab5ac3224ab0bc4c00340c28da4f..c2dc95e003e61ea49aba9ce0f345f1f425e8a587 100644 (file)
@@ -15626,3 +15626,66 @@ int UtcDaliActorDestructWorkerThreadN(void)
 
   END_TEST;
 }
+
+int UtcDaliActorIgnored(void)
+{
+  TestApplication application;
+
+  Actor   parent = Actor::New();
+  parent.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  application.GetScene().Add(parent);
+
+  Actor child1 = Actor::New();
+  child1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  child1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  parent.Add(child1);
+
+  Actor child2 = Actor::New();
+  child2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  child2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  parent.Add(child2);
+
+  DALI_TEST_EQUALS(child1.IsIgnored(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS(child2.IsIgnored(), false, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+
+  Vector3 childPosition1 = child1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  Vector3 childPosition2 = child2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  DALI_TEST_EQUALS(childPosition1, childPosition2, TEST_LOCATION);
+
+  parent.SetProperty(Actor::Property::POSITION, Vector2(100, 100));
+
+  application.SendNotification();
+  application.Render(0);
+
+  childPosition1 = child1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  childPosition2 = child2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  DALI_TEST_EQUALS(childPosition1, childPosition2, TEST_LOCATION);
+  DALI_TEST_EQUALS(childPosition1, Vector3(100, 100, 0), TEST_LOCATION);
+
+  child2.SetIgnored(true);
+  parent.SetProperty(Actor::Property::POSITION, Vector2(200, 200));
+
+  application.SendNotification();
+  application.Render(0);
+
+  childPosition1 = child1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  childPosition2 = child2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  DALI_TEST_NOT_EQUALS(childPosition1, childPosition2, 0.00001f, TEST_LOCATION);
+  DALI_TEST_EQUALS(childPosition1, Vector3(200, 200, 0), TEST_LOCATION);
+
+  child2.SetIgnored(false);
+
+  application.SendNotification();
+  application.Render(0);
+
+  childPosition1 = child1.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  childPosition2 = child2.GetProperty<Vector3>(Actor::Property::WORLD_POSITION);
+  DALI_TEST_EQUALS(childPosition1, childPosition2, TEST_LOCATION);
+  DALI_TEST_EQUALS(childPosition1, Vector3(200, 200, 0), TEST_LOCATION);
+
+  END_TEST;
+}
\ No newline at end of file
index 39ea47ccfedc32f3b3281c1862a84ba9b10ae402..a391a5611ab9c1a9bff948cd693b892cdd72d76d 100644 (file)
@@ -371,7 +371,7 @@ void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorP
  * @brief Get the stack of visibility changed actors.
  * @return The global visibility changed actors stack.
  */
-ActorContainer& GetVisibilityChagnedActorStack()
+ActorContainer& GetVisibilityChangedActorStack()
 {
   static ActorContainer gVisibilityChangedActorStack; ///< Stack of visibility changed actors. Latest actor is the latest visibility changed actor.
   return gVisibilityChangedActorStack;
@@ -720,9 +720,9 @@ Matrix Actor::GetCurrentWorldMatrix() const
 
 ActorPtr Actor::GetVisiblityChangedActor()
 {
-  if(!GetVisibilityChagnedActorStack().empty())
+  if(!GetVisibilityChangedActorStack().empty())
   {
-    return GetVisibilityChagnedActorStack().back();
+    return GetVisibilityChangedActorStack().back();
   }
   return ActorPtr();
 }
@@ -1245,6 +1245,7 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mIsRoot(ROOT_LAYER == derivedType),
   mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
   mIsOnScene(false),
+  mIsIgnored(false),
   mSensitive(true),
   mLeaveRequired(false),
   mKeyboardFocusable(false),
@@ -1728,12 +1729,12 @@ void Actor::SetParent(ActorParent* parent, bool notify)
     // Push the actor at the stack.
     // Note that another actor's visibility could be changed during visibility change callback.
     // So we need to stack those actors, and then use it.
-    GetVisibilityChagnedActorStack().emplace_back(this);
+    GetVisibilityChangedActorStack().emplace_back(this);
 
     EmitInheritedVisibilityChangedSignalRecursively(visiblility);
 
     // Pop the actor from the stack now
-    GetVisibilityChagnedActorStack().pop_back();
+    GetVisibilityChangedActorStack().pop_back();
   }
 }
 
@@ -1915,7 +1916,7 @@ void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
     // Push the actor at the stack.
     // Note that another actor's visibility could be changed during visibility change callback.
     // So we need to stack those actors, and then use it.
-    GetVisibilityChagnedActorStack().emplace_back(this);
+    GetVisibilityChangedActorStack().emplace_back(this);
 
     // Emit the signal on this actor and all its children
     mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
@@ -1926,7 +1927,7 @@ void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
     }
 
     // Pop the actor from the stack now
-    GetVisibilityChagnedActorStack().pop_back();
+    GetVisibilityChangedActorStack().pop_back();
   }
 }
 
@@ -1989,6 +1990,20 @@ void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
   SetUpdateAreaHintMessage(GetEventThreadServices(), GetNode(), updateAreaHint);
 }
 
+void Actor::SetIgnored(bool ignored)
+{
+  if(ignored != mIsIgnored)
+  {
+    mIsIgnored = ignored;
+    SetIgnoredMessage(GetEventThreadServices(), GetNode(), mIsIgnored);
+  }
+}
+
+bool Actor::IsIgnored() const
+{
+  return mIsIgnored;
+}
+
 } // namespace Internal
 
 } // namespace Dali
index ec607ac3bba102b0f691751a4983d5b299bea5e4..1743c3c06c2e6e5782b203a2cd22526f1d9b08ed 100644 (file)
@@ -1074,6 +1074,16 @@ public:
    */
   float GetMaximumSize(Dimension::Type dimension) const;
 
+  /**
+   * @copydoc Dali::Actor::SetIgnored
+   */
+  void SetIgnored(bool ignored);
+
+  /**
+   * @copydoc Dali::Actor::IsIgnored
+   */
+  bool IsIgnored() const;
+
   /**
    * @copydoc Dali::Actor::AddRenderer()
    */
@@ -1240,7 +1250,7 @@ public:
    */
   bool IsHittable() const
   {
-    return (IsUserInteractionEnabled()) && IsSensitive() && IsVisible() && (GetCurrentWorldColor().a > FULLY_TRANSPARENT) && IsNodeConnected();
+    return (IsUserInteractionEnabled()) && (!IsIgnored()) && IsSensitive() && IsVisible() && (GetCurrentWorldColor().a > FULLY_TRANSPARENT) && IsNodeConnected();
   }
 
   /**
@@ -2079,6 +2089,7 @@ protected:
   const bool               mIsRoot : 1;                    ///< Flag to identify the root actor
   const bool               mIsLayer : 1;                   ///< Flag to identify that this is a layer
   bool                     mIsOnScene : 1;                 ///< Flag to identify whether the actor is on-scene
+  bool                     mIsIgnored : 1;                 ///< Flag to identify whether the actor is ignored or not.
   bool                     mSensitive : 1;                 ///< Whether the actor emits touch event signals
   bool                     mLeaveRequired : 1;             ///< Whether a touch event signal is emitted when the a touch leaves the actor's bounds
   bool                     mKeyboardFocusable : 1;         ///< Whether the actor should be focusable by keyboard navigation
index f7538c33aec6467119353be3d2ebbaa28f7b38a6..53051ab3f319551a2a5bfb179f82bc60e071e9c0 100644 (file)
@@ -52,7 +52,8 @@ struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface
 
   bool DescendActorHierarchy(Actor* actor) override
   {
-    return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
+    return (!actor->IsIgnored()) &&
+           actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
 
index 1eda7519b24622fa4e116c1039887019195d8335..b9abab51833e105ffe30a328dc3cf871d3379792 100644 (file)
@@ -136,7 +136,8 @@ struct ActorTouchableCheck : public HitTestInterface
 
   bool DescendActorHierarchy(Actor* actor) override
   {
-    return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
+    return (!actor->IsIgnored()) &&
+           actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
 
index 6f6cfacd6066f2954ec6b8a563a43bd48db22055..179797d8ab50b76c70f670fde6b9ef59e5617403 100644 (file)
@@ -242,7 +242,8 @@ struct ActorHoverableCheck : public HitTestAlgorithm::HitTestInterface
 
   bool DescendActorHierarchy(Actor* actor) override
   {
-    return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
+    return (!actor->IsIgnored()) &&
+           actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
 
index 98714fce925906e8f94ac1451ade2988a3cf334c..cffded57b56d9cd79c0b83226a2d9eb49dd5944b 100644 (file)
@@ -150,7 +150,7 @@ bool CompareItems3DWithClipping(const RenderInstructionProcessor::SortAttributes
  * @param renderList to add the item to
  * @param renderable Node-Renderer pair
  * @param viewMatrix used to calculate modelview matrix for the item
- * @param viewMatrixChanged Whether view matrix chagned for this time or not.
+ * @param viewMatrixChanged Whether view matrix changed for this time or not.
  * @param camera The camera used to render
  * @param isLayer3d Whether we are processing a 3D layer or not
  * @param viewportSet Whether the viewport is set or not
@@ -312,7 +312,7 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
  * @param renderList to add the items to
  * @param renderers to render NodeRendererContainer Node-Renderer pairs
  * @param viewMatrix used to calculate modelview matrix for the items
- * @param viewMatrixChanged Whether view matrix chagned for this time or not.
+ * @param viewMatrixChanged Whether view matrix changed for this time or not.
  * @param camera The camera used to render
  * @param isLayer3d Whether we are processing a 3D layer or not
  * @param viewportSet Whether the viewport is set or not
index cf7816fd2f973c9b5cf88fbb4af237657387deef..462c5f05db9d94e435d78917a2a1ab9e46df9225 100644 (file)
@@ -90,7 +90,7 @@ void AddRenderablesForTask(BufferIndex updateBufferIndex,
                            bool&       keepRendering)
 {
   // Short-circuit for invisible nodes
-  if(!node.IsVisible(updateBufferIndex))
+  if(!(node.IsVisible(updateBufferIndex) && !node.IsIgnored()))
   {
     node.GetPartialRenderingData().mVisible = false;
     return;
index 775e3860b9bf0b79b5da527a1ae87e5282e03c9a..9173296bfe8d0fd29ebd24e3311fb7e49fa5d394 100644 (file)
@@ -254,6 +254,7 @@ TransformId TransformManager::CreateTransform()
     mSizeBase.PushBack(Vector3(0.0f, 0.0f, 0.0f));
     mComponentDirty.PushBack(CLEAN_FLAG);
     mWorldMatrixDirty.PushBack(false);
+    mIgnored.PushBack(false);
   }
   else
   {
@@ -271,6 +272,7 @@ TransformId TransformManager::CreateTransform()
     mSizeBase[mComponentCount]         = Vector3(0.0f, 0.0f, 0.0f);
     mComponentDirty[mComponentCount]   = CLEAN_FLAG;
     mWorldMatrixDirty[mComponentCount] = false;
+    mIgnored[mComponentCount] = false;
   }
 
   mComponentCount++;
@@ -293,6 +295,7 @@ void TransformManager::RemoveTransform(TransformId id)
   mSizeBase[index]                       = mSizeBase[mComponentCount];
   mComponentDirty[index]                 = mComponentDirty[mComponentCount];
   mWorldMatrixDirty[index]               = mWorldMatrixDirty[mComponentCount];
+  mIgnored[index]                        = mIgnored[mComponentCount];
   mBoundingSpheres[index]                = mBoundingSpheres[mComponentCount];
 
   TransformId lastItemId = mComponentId[mComponentCount];
@@ -363,6 +366,8 @@ void TransformManager::ResetToBaseValue()
   }
 }
 
+int cnt = 0;
+
 bool TransformManager::Update()
 {
   mUpdated = false;
@@ -385,6 +390,8 @@ bool TransformManager::Update()
     mReorder = false;
   }
 
+  cnt = 0;
+
   // Iterate through all components to compute its world matrix
   Vector3       centerPosition;
   Vector3       localPosition;
@@ -395,6 +402,13 @@ bool TransformManager::Update()
     if(DALI_LIKELY(mInheritanceMode[i] != DONT_INHERIT_TRANSFORM && mParent[i] != INVALID_TRANSFORM_ID))
     {
       const TransformId& parentIndex = mIds[mParent[i]];
+      mIgnored[i] = mIgnored[parentIndex] || mTxComponentStatic[i].mIgnored;
+      if(mIgnored[i])
+      {
+        mComponentDirty[i] >>= 1u; ///< age down.
+        continue;
+      }
+
       if(DALI_LIKELY(mInheritanceMode[i] == INHERIT_ALL))
       {
         if(mComponentDirty[i] || mWorldMatrixDirty[parentIndex])
@@ -483,6 +497,13 @@ bool TransformManager::Update()
     }
     else // Component has no parent or doesn't inherit transform
     {
+      mIgnored[i] = mTxComponentStatic[i].mIgnored;
+      if(mIgnored[i])
+      {
+        mComponentDirty[i] >>= 1u; ///< age down.
+        continue;
+      }
+
       if(mComponentDirty[i])
       {
         // TODO : We need to check mComponentDirty since we have to check the size changeness.
@@ -534,6 +555,7 @@ void TransformManager::SwapComponents(unsigned int i, unsigned int j)
   std::swap(mComponentDirty[i], mComponentDirty[j]);
   std::swap(mBoundingSpheres[i], mBoundingSpheres[j]);
   std::swap(mWorld[i], mWorld[j]);
+  std::swap(mIgnored[i], mIgnored[j]);
 
   mIds[mComponentId[i]] = i;
   mIds[mComponentId[j]] = j;
@@ -616,6 +638,7 @@ void TransformManager::ReorderComponents()
     mComponentDirty.Resize(mComponentCount);
     mWorldMatrixDirty.Resize(mComponentCount);
     mOrderedComponents.Resize(mComponentCount);
+    mIgnored.Resize(mComponentCount);
 
     mTxComponentAnimatable.ShrinkToFit();
     mTxComponentStatic.ShrinkToFit();
@@ -631,6 +654,7 @@ void TransformManager::ReorderComponents()
     mComponentDirty.ShrinkToFit();
     mWorldMatrixDirty.ShrinkToFit();
     mOrderedComponents.ShrinkToFit();
+    mIgnored.ShrinkToFit();
   }
 #endif
 }
@@ -1124,6 +1148,13 @@ void TransformManager::SetPositionUsesAnchorPoint(TransformId id, bool value)
   SetTransfromPropertyIfChanged(mTxComponentStatic[index].mPositionUsesAnchorPoint, mComponentDirty[index], mDirtyFlags, value, STATIC_COMPONENT_FLAG);
 }
 
+void TransformManager::SetIgnored(TransformId id, bool value)
+{
+  TransformId index(mIds[id]);
+
+  SetTransfromPropertyIfChanged(mTxComponentStatic[index].mIgnored, mComponentDirty[index], mDirtyFlags, value, STATIC_COMPONENT_FLAG);
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index 4ba303f421de4de3fc3ac39204bb4ad62537c103..698f12a25cbd944206fe103d93b23b2333fdcdb5 100644 (file)
@@ -57,13 +57,15 @@ struct TransformComponentStatic
   TransformComponentStatic()
   : mAnchorPoint(AnchorPoint::DEFAULT),
     mParentOrigin(ParentOrigin::DEFAULT),
-    mPositionUsesAnchorPoint(true)
+    mPositionUsesAnchorPoint(true),
+    mIgnored(false)
   {
   }
 
   Vector3 mAnchorPoint;
   Vector3 mParentOrigin;
   bool    mPositionUsesAnchorPoint;
+  bool    mIgnored;
 };
 
 enum InheritanceMode
@@ -79,6 +81,7 @@ enum TransformManagerProperty
 {
   TRANSFORM_PROPERTY_POSITION = 0,
   TRANSFORM_PROPERTY_SCALE,
+  TRANSFORM_PROPERTY_IGNORED,
   TRANSFORM_PROPERTY_ANCHOR_POINT,
   TRANSFORM_PROPERTY_PARENT_ORIGIN,
   TRANSFORM_PROPERTY_SIZE,
@@ -370,6 +373,13 @@ public:
    */
   void SetPositionUsesAnchorPoint(TransformId id, bool value);
 
+  /**
+   * @brief Sets ignored value.
+   * @param[in] id Id of the transform component.
+   * @param[in] value True if the component is ignored.
+   */
+  void SetIgnored(TransformId id, bool value);
+
 private:
   //Helper struct to order components
   struct SOrderItem
@@ -422,6 +432,7 @@ private:
                                                                         ///< Or If we change static component changed, flag become non-zero. Age down at Update time.
                                                                         ///< Note that we don't replace dirty flag as BAKE even if we call Bake operation.
                                                                         ///< (Since single dirty flag controls multiple animatable properties ; Position, Size, Scale, Orientation.)
+  Vector<bool>       mIgnored;                                          ///< True if the component is ignored.
   Vector<bool>       mWorldMatrixDirty;                                 ///< 1u if the world matrix has been updated in this frame, 0 otherwise
   Vector<SOrderItem> mOrderedComponents;                                ///< Used to reorder components when hierarchy changes
 
index 1873e30bba38eb42c2de2f1f9d482ba1069f665a..8cd30663520d690e1b1922ba7e1f04f2b5196441 100644 (file)
@@ -104,6 +104,11 @@ inline NodePropertyFlags UpdateNodes(Node&                   node,
                                      PropertyOwnerContainer& postPropertyOwners,
                                      bool                    updated)
 {
+  if(DALI_UNLIKELY(node.IsIgnored())) // almost never ever true
+  {
+    return NodePropertyFlags::NOTHING;
+  }
+
   // Apply constraints to the node
   ConstrainPropertyOwner(node, updateBufferIndex);
   if(!node.GetPostConstraints().Empty())
@@ -159,14 +164,14 @@ NodePropertyFlags UpdateNodeTree(Layer&                  rootNode,
   DALI_ASSERT_DEBUG(rootNode.IsRoot());
 
   // Short-circuit for invisible nodes
-  if(DALI_UNLIKELY(!rootNode.IsVisible(updateBufferIndex))) // almost never ever true
+  if(DALI_UNLIKELY(!(rootNode.IsVisible(updateBufferIndex) && !rootNode.IsIgnored()))) // almost never ever true
   {
     return NodePropertyFlags::NOTHING;
   }
 
   // If the root node was not previously visible
   BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u;
-  if(DALI_UNLIKELY(!rootNode.IsVisible(previousBuffer))) // almost never ever true
+  if(DALI_UNLIKELY(!(rootNode.IsVisible(previousBuffer) && !rootNode.IsIgnored()))) // almost never ever true
   {
     // The node was skipped in the previous update; it must recalculate everything
     rootNode.SetAllDirtyFlags();
index e183746945c9edd6ba26737cf4ecae93efcff920..010f499f5cc147b5b03f6e61496e8687601dbb1f 100644 (file)
@@ -116,7 +116,8 @@ Node::Node()
   mTransparent(false),
   mUpdateAreaChanged(false),
   mUpdateAreaUseSize(true),
-  mUseTextureUpdateArea(false)
+  mUseTextureUpdateArea(false),
+  mIgnored(false)
 {
 #ifdef DEBUG_ENABLED
   gNodeCount++;
@@ -154,6 +155,7 @@ void Node::CreateTransform(SceneGraph::TransformManager* transformManager)
 
   // Set whether the position should use the anchor point
   transformManager->SetPositionUsesAnchorPoint(createdTransformId, mPositionUsesAnchorPoint);
+  transformManager->SetIgnored(createdTransformId, mIgnored);
 
   // Set TransformId after initialize done.
   mTransformManagerData.mId = createdTransformId;
index 9fe8399c531bfd9c39e816c972767a64e43231b6..94bbe798889de0fc6629a6ba28bf2d592a60ac15 100644 (file)
@@ -447,6 +447,32 @@ public:
     mAnchorPoint.Set(0, anchor);
   }
 
+  /**
+   * Sets flag to identify whether the node is ignored or not.
+   * @param[in] ignored True to make the node be ignored.
+   */
+  void SetIgnored(const bool ignored)
+  {
+    if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID && mIgnored != ignored)
+    {
+      mIgnored = ignored;
+      mTransformManagerData.Manager()->SetIgnored(mTransformManagerData.Id(), mIgnored);
+    }
+  }
+
+  /**
+   * Retrieve Whether the node is ignored or not.
+   * @return True if the node is ignored.
+   */
+  bool IsIgnored() const
+  {
+    if(mTransformManagerData.Id() != INVALID_TRANSFORM_ID)
+    {
+      return mIgnored;
+    }
+    return false;
+  }
+
   /**
    * Retrieve the local position of the node, relative to its parent.
    * @param[in] bufferIndex The buffer to read from.
@@ -1173,6 +1199,7 @@ protected:
   bool               mUpdateAreaChanged : 1;       ///< True if the update area of the node is changed.
   bool               mUpdateAreaUseSize : 1;       ///< True if the update area of the node is same as node size.
   bool               mUseTextureUpdateArea : 1;    ///< Whether the actor uses the update area of the texture instead of its own.
+  bool               mIgnored : 1;                 ///< Whether the node is ignored or not.
 
   // Changes scope, should be at end of class
   DALI_LOG_OBJECT_STRING_DECLARATION;
@@ -1323,6 +1350,17 @@ inline void SetPositionUsesAnchorPointMessage(EventThreadServices& eventThreadSe
   new(slot) LocalType(&node, &Node::SetPositionUsesAnchorPoint, positionUsesAnchorPoint);
 }
 
+inline void SetIgnoredMessage(EventThreadServices& eventThreadServices, const Node& node, bool ignored)
+{
+  using LocalType = MessageValue1<Node, bool>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&node, &Node::SetIgnored, ignored);
+}
+
 inline void SetUpdateAreaHintMessage(EventThreadServices& eventThreadServices, const Node& node, const Vector4& updateAreaHint)
 {
   using LocalType = MessageValue1<Node, Vector4>;
index 6fad66f875d604d6faab390ac0d23b16d9dde66e..65a2fdc442e2897fbf33587bd41f991bc0fd2a76 100644 (file)
@@ -198,6 +198,17 @@ float Actor::GetRelayoutSize(Dimension::Type dimension) const
   return GetImplementation(*this).GetRelayoutSize(dimension);
 }
 
+void Actor::SetIgnored(bool ignored)
+{
+  GetImplementation(*this).SetIgnored(ignored);
+}
+
+bool Actor::IsIgnored() const
+{
+  return GetImplementation(*this).IsIgnored();
+}
+
+
 Actor::TouchEventSignalType& Actor::TouchedSignal()
 {
   return GetImplementation(*this).TouchedSignal();
index 87a3a35c2408a82009154ec3fdadcb216981bd33..75c2d1771cb4ec27de5f3eb7b1973bfb6f9dce0e 100644 (file)
@@ -1124,6 +1124,24 @@ public:
    */
   float GetRelayoutSize(Dimension::Type dimension) const;
 
+  /**
+   * @brief Sets a flag to identify whether the Actor is ignored or not.
+   * If the actor is marked as ignored, it will not be rendered and will be excluded from render thread computation.
+   * So, the current properties like WorldPosition and WorldColor become inaccurate.
+   *
+   * @SINCE_2_4.21
+   * @param[in] ignored True to make the actor be ignored.
+   */
+  void SetIgnored(bool ignored);
+
+  /**
+   * @brief Returns whether the Actor is ignored or not.
+   *
+   * @SINCE_2_4.21
+   * @return Return True if the Actor is ignored.
+   */
+  bool IsIgnored() const;
+
 public: // Renderer
   /**
    * @brief Adds a renderer to this actor.