Reorder node's children only required case. 33/286133/9
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 28 Dec 2022 12:33:23 +0000 (21:33 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Mon, 30 Jan 2023 08:17:14 +0000 (08:17 +0000)
If all of my children's depth index didn't changed,
we don't need to re-sort this sorted node value.

This patch add the flag of children-reorder, and
sort it only if my direct children's depth index changed.

Change-Id: I349aa50337b750504056ac0d57896e896cd9c32e
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/update/manager/update-manager.cpp
dali/internal/update/nodes/node-declarations.h
dali/internal/update/nodes/node.h

index c9060d2..1abac25 100644 (file)
@@ -130,22 +130,6 @@ inline void EraseUsingDiscardQueue(OwnerKeyContainer<Type>& container, const Mem
   }
 }
 
-/**
- * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
- * @param[in] node The node whose hierarchy to descend
- */
-void SortSiblingNodesRecursively(Node& node)
-{
-  NodeContainer& container = node.GetChildren();
-  std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
-
-  // Descend tree and sort as well
-  for(auto&& iter : container)
-  {
-    SortSiblingNodesRecursively(*iter);
-  }
-}
-
 } // unnamed namespace
 
 /**
@@ -1278,19 +1262,18 @@ void UpdateManager::SetLayerDepths(const SortedLayerPointers& layers, const Laye
 
 void UpdateManager::SetDepthIndices(OwnerPointer<NodeDepths>& nodeDepths)
 {
-  // note,this vector is already in depth order. It could be used as-is to
-  // remove sorting in update algorithm. However, it lacks layer boundary markers.
-  for(auto&& iter : nodeDepths->nodeDepths)
-  {
-    iter.node->SetDepthIndex(iter.sortedDepth);
-  }
-
-  for(auto&& scene : mImpl->scenes)
+  // note, this vector is already in depth order.
+  // So if we reverse iterate, we can assume that
+  // my descendant node's depth index are updated.
+  for(auto rIter = nodeDepths->nodeDepths.rbegin(), rEndIter = nodeDepths->nodeDepths.rend(); rIter != rEndIter; rIter++)
   {
-    if(scene)
+    auto* node = rIter->node;
+    node->SetDepthIndex(rIter->sortedDepth);
+    if(node->IsChildrenReorderRequired())
     {
-      // Go through node hierarchy and rearrange siblings according to depth-index
-      SortSiblingNodesRecursively(*scene->root);
+      // Reorder children container only if sibiling order changed.
+      NodeContainer& container = node->GetChildren();
+      std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
     }
   }
 }
index 1867063..c6fb7aa 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_NODE_DECLARATIONS_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,13 +43,13 @@ using NodeConstIter = NodeContainer::ConstIterator;
 enum class NodePropertyFlags : uint8_t
 // 8 bits is enough for 5 flags (compiler will check it)
 {
-  NOTHING       = 0x000,
-  TRANSFORM     = 0x001,
-  VISIBLE       = 0x002,
-  COLOR         = 0x004,
-  CHILD_DELETED = 0x008,
-  DEPTH_INDEX   = 0x010,
-  ALL           = (DEPTH_INDEX << 1) - 1 // all the flags
+  NOTHING          = 0x000,
+  TRANSFORM        = 0x001,
+  VISIBLE          = 0x002,
+  COLOR            = 0x004,
+  CHILD_DELETED    = 0x008,
+  CHILDREN_REORDER = 0x010,
+  ALL              = (CHILDREN_REORDER << 1) - 1 // all the flags
 };
 
 struct NodeDepthPair
index 4182374..ca9d5a8 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_NODE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -802,7 +802,11 @@ public:
   {
     if(depthIndex != mDepthIndex)
     {
-      SetDirtyFlag(NodePropertyFlags::DEPTH_INDEX);
+      if(mParent)
+      {
+        // Send CHILDREN_REORDER dirty flag only if my depth index changed.
+        mParent->SetDirtyFlag(NodePropertyFlags::CHILDREN_REORDER);
+      }
       SetUpdated(true);
       mDepthIndex = depthIndex;
     }
@@ -818,6 +822,16 @@ public:
   }
 
   /**
+   * @brief Get whether children sibiling order need to be changed. s.t. child's depth index changed.
+   * @note It will be reset when mDirtyFlag reseted.
+   * @return True if children sibiling order need to be changed.
+   */
+  uint32_t IsChildrenReorderRequired() const
+  {
+    return mDirtyFlags & NodePropertyFlags::CHILDREN_REORDER;
+  }
+
+  /**
    * @brief Sets the boolean which states whether the position should use the anchor-point.
    * @param[in] positionUsesAnchorPoint True if the position should use the anchor-point
    */
@@ -930,10 +944,10 @@ private: // from NodeDataProvider
 
 private:
   // Delete copy and move
-  Node(const Node&)                = delete;
-  Node(Node&&)                     = delete;
+  Node(const Node&) = delete;
+  Node(Node&&)      = delete;
   Node& operator=(const Node& rhs) = delete;
-  Node& operator=(Node&& rhs)      = delete;
+  Node& operator=(Node&& rhs) = delete;
 
   /**
    * Recursive helper to disconnect a Node and its children.