Simplified actor depth traversal algorithms 13/132813/6
authorDavid Steele <david.steele@samsung.com>
Wed, 7 Jun 2017 19:37:51 +0000 (20:37 +0100)
committerDavid Steele <david.steele@samsung.com>
Mon, 12 Jun 2017 12:49:02 +0000 (13:49 +0100)
Instead of having a complex sibling order and hierarchy depth combination,
changed to use actor order in mChildren; Sibling operations now move
the actor pointers in this array.

Automatically regenerates a depth index for every actor in the tree
when any part of the tree changes. (i.e. actor add/remove, raise/lower etc)
at the end of an event processing cycle, and resends a list of nodes
to UpdateManager in a single message.

Change-Id: I1f716132f0e3a13fc21fbebf188287dc893956ee
Signed-off-by: David Steele <david.steele@samsung.com>
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali-internal/utc-Dali-Internal-ActorDepth.cpp [deleted file]
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/update/manager/update-manager.h

index 91eb1f443173fc17689233714d079504d0b09618..0398c40e02d41586be75c91e086bce6917950a32 100644 (file)
@@ -11,7 +11,6 @@ SET(TC_SOURCES
         utc-Dali-Internal-FixedSizeMemoryPool.cpp
         utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
         utc-Dali-Internal-FrustumCulling.cpp
-        utc-Dali-Internal-ActorDepth.cpp
         utc-Dali-Internal-PixelData.cpp
 )
 
diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-ActorDepth.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-ActorDepth.cpp
deleted file mode 100644 (file)
index f5a9482..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include <iostream>
-
-#include <stdlib.h>
-#include <dali/public-api/dali-core.h>
-
-#include <dali-test-suite-utils.h>
-#include <dali/devel-api/actors/actor-devel.h>
-
-// Internal headers are allowed here
-#define protected public
-#include <dali/internal/event/actors/actor-impl.h>
-
-using namespace Dali;
-
-void utc_dali_internal_actor_depth_startup()
-{
-  test_return_value = TET_UNDEF;
-}
-
-void utc_dali_internal_actor_depth_cleanup()
-{
-  test_return_value = TET_PASS;
-}
-
-Actor CreateActor( Actor parent, int siblingOrder, const char* name )
-{
-  Actor actor = Actor::New();
-  actor.SetProperty( DevelActor::Property::SIBLING_ORDER, siblingOrder);
-  actor.SetName( name );
-  parent.Add(actor);
-  return actor;
-}
-
-void PrintActor(Dali::Actor a, int depth)
-{
-  int siblingOrder;
-  Dali::Property::Value v = a.GetProperty( Dali::DevelActor::Property::SIBLING_ORDER );
-  v.Get(siblingOrder);
-
-  Dali::Internal::Actor& actorImpl = GetImplementation(a);
-  for( int i=0; i<depth; ++i)
-    std::cout << "  ";
-  std::cout << "Actor: " << a.GetName() << "(" << a.GetId() << ") siblingOrder: " <<
-    siblingOrder << " depthOrder: " << actorImpl.GetSortingDepth() << std::endl;
-}
-
-void PrintActorTree( Dali::Actor a, int depth )
-{
-  PrintActor( a, depth );
-  for( unsigned int i=0; i<a.GetChildCount(); ++i )
-  {
-    PrintActorTree( a.GetChildAt(i), depth+1 );
-  }
-}
-
-void PrintNode( Dali::Internal::ActorDepthTreeNode& node, int depth )
-{
-  for( int i=0; i<depth; ++i)
-    std::cout << "  ";
-  std::cout << "Node: " << &node << "  siblingOrder:" << node.mSiblingOrder << " Actors:";
-  for( std::vector<Internal::Actor*>::iterator iter = node.mActors.begin() ;
-       iter != node.mActors.end(); ++iter )
-  {
-    std::cout << (*iter)->GetName() << ", ";
-  }
-  std::cout << std::endl;
-
-  if( node.mFirstChildNode )
-    PrintNode( *node.mFirstChildNode, depth+1);
-
-  if( node.mNextSiblingNode )
-  {
-    PrintNode( *node.mNextSiblingNode, depth );
-  }
-}
-
-void CheckNodeForActor( Dali::Internal::ActorDepthTreeNode*node, Actor actor, const char* loc )
-{
-  bool found = false;
-  Dali::Internal::Actor& actorImpl = Dali::GetImplementation(actor);
-
-  for( std::vector<Internal::Actor*>::iterator iter = node->mActors.begin(); iter != node->mActors.end(); ++iter )
-  {
-    if( *iter == &actorImpl )
-    {
-      found = true;
-      break;
-    }
-  }
-  DALI_TEST_EQUALS( found, true, loc );
-}
-
-unsigned int GetActorCount( Dali::Internal::ActorDepthTreeNode*node )
-{
-  unsigned int size = node->mActors.size();
-
-  for( Dali::Internal::ActorDepthTreeNode* childNode = node->mFirstChildNode;
-       childNode != NULL;
-       childNode = childNode->mNextSiblingNode )
-  {
-    size += GetActorCount( childNode );
-  }
-
-  return size;
-}
-
-int UtcDaliActorDepthTreeTest01(void)
-{
-  TestApplication application;
-  tet_infoline("Testing Actor tree depth");
-
-  Stage stage = Stage::GetCurrent();
-
-  Actor Root = CreateActor(stage.GetRootLayer(), 0, "ROOT" );
-  Actor A = CreateActor( Root, 0, "A");
-  Actor B = CreateActor( Root, 2, "B");
-  Actor C = CreateActor( Root, 0, "C");
-  Actor D = CreateActor( Root, 1, "D");
-
-  Actor E = CreateActor(A, 0, "E");
-  Actor F = CreateActor(A, 2, "F");
-  Actor G = CreateActor(A, 1, "G");
-
-  Actor H = CreateActor(B, 2, "H");
-  Actor I = CreateActor(B, 1, "I");
-  Actor J = CreateActor(B, 0, "J");
-
-  Actor K = CreateActor(C, 1, "K");
-  Actor L = CreateActor(C, 2, "L");
-  Actor M = CreateActor(C, 0, "M");
-
-  Actor N = CreateActor(D, 2, "N");
-  Actor O = CreateActor(D, 2, "O");
-  Actor P = CreateActor(D, 1, "P");
-
-  PrintActorTree( Root, 0 );
-
-  Internal::Actor& rootLayerImpl = GetImplementation(Root);
-
-  Internal::DepthNodeMemoryPool nodeMemoryPool;
-  Internal::ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) Internal::ActorDepthTreeNode( &rootLayerImpl, 0 );
-  rootLayerImpl.BuildDepthTree( nodeMemoryPool, rootNode ) ;
-
-  int depth=0;
-  PrintNode( *rootNode, depth );
-
-  // Check that first child node contains actors A and C
-  // check that first grand child node contains actors E, M
-  // check that it's sibling node contains actors G, K
-  // check that it's sibling node contains actors F, L
-  // Check that tree only contains 16 actors.
-  CheckNodeForActor( rootNode->mFirstChildNode, A, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode, C, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, E, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, M, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode, G, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode, K, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, F, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, L, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mNextSiblingNode->mNextSiblingNode, B, TEST_LOCATION );
-
-  unsigned int actorCount = GetActorCount( rootNode );
-  DALI_TEST_EQUALS( actorCount, 17, TEST_LOCATION );
-
-  END_TEST;
-}
-
-
-
-int UtcDaliActorDepthTreeTest02(void)
-{
-  TestApplication application;
-  tet_infoline("Testing Actor tree depth");
-
-  Stage stage = Stage::GetCurrent();
-
-  Actor Root = CreateActor(stage.GetRootLayer(), 0, "ROOT" );
-  Actor A = CreateActor( Root, 0, "A");
-  Actor B = CreateActor( Root, 0, "B");
-  Actor C = CreateActor( Root, 0, "C");
-  Actor D = CreateActor( Root, 0, "D");
-
-  Actor E = CreateActor(A, 0, "E");
-  Actor F = CreateActor(A, 0, "F");
-  Actor G = CreateActor(A, 0, "G");
-
-  Actor H = CreateActor(B, 0, "H");
-  Actor I = CreateActor(B, 0, "I");
-  Actor J = CreateActor(B, 0, "J");
-
-  Actor K = CreateActor(C, 0, "K");
-  Actor L = CreateActor(C, 0, "L");
-  Actor M = CreateActor(C, 0, "M");
-
-  Actor N = CreateActor(D, 0, "N");
-  Actor O = CreateActor(D, 0, "O");
-  Actor P = CreateActor(D, 0, "P");
-
-  PrintActorTree( Root, 0 );
-
-  Internal::Actor& rootLayerImpl = GetImplementation(Root);
-
-  Internal::DepthNodeMemoryPool nodeMemoryPool;
-  Internal::ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) Internal::ActorDepthTreeNode( &rootLayerImpl, 0 );
-  rootLayerImpl.BuildDepthTree( nodeMemoryPool, rootNode ) ;
-
-  int depth=0;
-  PrintNode( *rootNode, depth );
-
-  CheckNodeForActor( rootNode->mFirstChildNode, A, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode, C, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, E, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, M, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, G, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, K, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, F, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode->mFirstChildNode, L, TEST_LOCATION );
-  CheckNodeForActor( rootNode->mFirstChildNode, B, TEST_LOCATION );
-
-  unsigned int actorCount = GetActorCount( rootNode );
-  DALI_TEST_EQUALS( actorCount, 17, TEST_LOCATION );
-
-  END_TEST;
-}
index aeeb91ed688f1c32c8c8900de7784b1f4898f58d..34ef21c00e45ce14a51f305335132432cc9b8153 100644 (file)
@@ -4734,9 +4734,14 @@ int UtcDaliActorLowerBelow(void)
   actorC.SetProperty( Actor::Property::WIDTH_RESIZE_POLICY, "FILL_TO_PARENT" );
   actorC.SetProperty( Actor::Property::HEIGHT_RESIZE_POLICY, "FILL_TO_PARENT" );
 
-  stage.Add( actorA );
-  stage.Add( actorB );
-  stage.Add( actorC );
+  Actor container = Actor::New();
+  container.SetParentOrigin( ParentOrigin::CENTER );
+  container.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  stage.Add( container );
+
+  container.Add( actorA );
+  container.Add( actorB );
+  container.Add( actorC );
 
   ResetTouchCallbacks();
 
@@ -4814,10 +4819,9 @@ int UtcDaliActorLowerBelow(void)
   indexB = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "2" );
   indexA = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "1" );
 
-  tet_infoline( "Testing B above A and C at bottom\n" );
-  bool BAC = ( indexB > indexA) &&  ( indexA > indexC ); // B at TOP, then A then C at bottom
-
-  DALI_TEST_EQUALS( BAC, true, TEST_LOCATION );
+  tet_infoline( "Testing render order is A, C, B" );
+  DALI_TEST_EQUALS( indexC > indexA, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( indexB > indexC, true, TEST_LOCATION );
 
   DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
   DALI_TEST_EQUALS( gTouchCallBackCalled2, true, TEST_LOCATION );
@@ -4825,9 +4829,9 @@ int UtcDaliActorLowerBelow(void)
 
   ResetTouchCallbacks();
 
-  tet_printf( "Lower actor B below Actor C leaving A on top\n" );
+  tet_printf( "Lower actor C below Actor A leaving B on top\n" );
 
-  DevelActor::LowerBelow( actorB, actorC );
+  DevelActor::LowerBelow( actorC, actorA );
   // Ensure sorting happens at end of Core::ProcessEvents() before next touch
   application.SendNotification();
   application.Render();
@@ -4845,19 +4849,18 @@ int UtcDaliActorLowerBelow(void)
   indexB = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "2" );
   indexA = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "1" );
 
-  bool ACB = ( indexA > indexC) &&  ( indexC > indexB ); // A on TOP, then C then B at bottom
+  DALI_TEST_EQUALS( indexA > indexC, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( indexB > indexA, true, TEST_LOCATION );
 
-  DALI_TEST_EQUALS( ACB, true, TEST_LOCATION );
-
-  DALI_TEST_EQUALS( gTouchCallBackCalled, true, TEST_LOCATION );
-  DALI_TEST_EQUALS( gTouchCallBackCalled2, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( gTouchCallBackCalled, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( gTouchCallBackCalled2, true, TEST_LOCATION );
   DALI_TEST_EQUALS( gTouchCallBackCalled3, false , TEST_LOCATION );
 
   ResetTouchCallbacks();
 
-  tet_printf( "Lower actor A below Actor C leaving C on top\n" );
+  tet_printf( "Lower actor B below Actor C leaving A on top\n" );
 
-  DevelActor::LowerBelow( actorA, actorC );
+  DevelActor::LowerBelow( actorB, actorC );
   // Ensure sorting happens at end of Core::ProcessEvents() before next touch
   application.SendNotification();
   application.Render();
@@ -4875,71 +4878,14 @@ int UtcDaliActorLowerBelow(void)
   indexB = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "2" );
   indexA = glSetUniformStack.FindIndexFromMethodAndParams( "uRendererColor",  "1" );
 
-  bool CAB = ( indexC > indexA) &&  ( indexA > indexB );
-
-  DALI_TEST_EQUALS( CAB, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( indexC > indexB, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( indexA > indexC, true, TEST_LOCATION );
 
   END_TEST;
 }
 
-int UtcDaliActorMaxSiblingOrder(void)
-{
-  tet_infoline( "UtcDaliActor De-fragment of sibling order once max index reached\n" );
-
-  TestApplication application;
-
-  int testOrders[] = { 0,1,3,5,17,998, 999 };
-  int resultingOrders[] = { 0,1,2,3,4,6,5 };
-
-  const int TEST_ORDERS_COUNT = sizeof( testOrders ) / sizeof( testOrders[0] );
-
-  Stage stage( Stage::GetCurrent() );
-
-  Actor parent = Actor::New();
-
-  for ( int index = 0; index < TEST_ORDERS_COUNT; index++ )
-  {
-    Actor newActor = Actor::New();
-    newActor.SetProperty(Dali::DevelActor::Property::SIBLING_ORDER, testOrders[index] );
-    parent.Add( newActor );
-  }
-  stage.Add( parent );
-
-  tet_printf( "Sibling Order %d children :",  parent.GetChildCount() );
-  for ( unsigned int index = 0; index < parent.GetChildCount(); index ++)
-  {
-    Actor sibling = parent.GetChildAt( index );
-    int siblingOrder = 0;
-    Property::Value value = sibling.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
-    value.Get( siblingOrder );
-    tet_printf( "%d, ", siblingOrder );
-  }
-  tet_printf( "\n" );
-
-  Actor sibling = parent.GetChildAt( 5 );
-  DevelActor::RaiseToTop( sibling );
-
-  // Ensure sorting happens at end of Core::ProcessEvents()
-  application.SendNotification();
-  application.Render();
-
-  tet_printf( "Sibling Order %d children :",  parent.GetChildCount() );
-  for ( unsigned int index = 0; index < parent.GetChildCount(); index ++)
-  {
-    Actor sibling = parent.GetChildAt( index );
-    int siblingOrder = 0;
-    Property::Value value = sibling.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
-    value.Get( siblingOrder );
-    tet_printf( "%d, ", siblingOrder );
-    DALI_TEST_EQUALS( siblingOrder,  resultingOrders[ index] , TEST_LOCATION );
-  }
-
-  tet_printf( "\n" );
-
-  END_TEST;
-}
 
-int UtcDaliActorRaiseAboveLowerBelowDifferentParentsN(void)
+int UtcDaliActorRaiseAboveDifferentParentsN(void)
 {
   tet_infoline( "UtcDaliActor RaiseToAbove test with actor and target actor having different parents \n" );
 
index 0dcdfa8976283dddf6d38980da6a5b190cc7794a..a8164ebc9ec78777317b39e4ac1f643292b7cfc0 100644 (file)
@@ -1417,16 +1417,16 @@ Renderer CreateRenderer( Actor actor, Geometry geometry, Shader shader, int dept
 
 Actor CreateActor( Actor parent, int siblingOrder, const char* location )
 {
-  Actor actor0 = Actor::New();
-  actor0.SetAnchorPoint(AnchorPoint::CENTER);
-  actor0.SetParentOrigin(AnchorPoint::CENTER);
-  actor0.SetPosition(0.0f,0.0f);
-  actor0.SetSize(100, 100);
-  actor0.SetProperty( Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder );
-  DALI_TEST_EQUALS( actor0.GetProperty<int>( Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location) );
-  parent.Add(actor0);
-
-  return actor0;
+  Actor actor = Actor::New();
+  actor.SetAnchorPoint(AnchorPoint::CENTER);
+  actor.SetParentOrigin(AnchorPoint::CENTER);
+  actor.SetPosition(0.0f,0.0f);
+  actor.SetSize(100, 100);
+  parent.Add(actor);
+  actor.SetProperty( Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder );
+  DALI_TEST_EQUALS( actor.GetProperty<int>( Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location) );
+
+  return actor;
 }
 
 int UtcDaliRendererRenderOrder2DLayer(void)
@@ -1562,7 +1562,7 @@ int UtcDaliRendererRenderOrder2DLayerMultipleRenderers(void)
   //Check that renderer0 has been rendered after renderer2
   DALI_TEST_GREATER( textureBindIndex[4], textureBindIndex[5], TEST_LOCATION );
 
-  //Check that renderer0 has been rendered after renderer2
+  //Check that renderer5 has been rendered after renderer2
   DALI_TEST_GREATER( textureBindIndex[5], textureBindIndex[0], TEST_LOCATION );
 
   //Check that renderer0 has been rendered after renderer2
index 134df1fcb5a297dacaae31fe5ed2743eb2d7be09..e0e1604143d34a26d0e875e4fb33c7d06abf9bc1 100644 (file)
@@ -93,32 +93,6 @@ inline const Vector2& GetDefaultDimensionPadding()
 
 const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET;
 
-int GetSiblingOrder( ActorPtr actor )
-{
-  Property::Value value  = actor->GetProperty(Dali::DevelActor::Property::SIBLING_ORDER );
-  int order;
-  value.Get( order );
-  return order;
-}
-
-bool ValidateActors( const Internal::Actor& actor, const Internal::Actor& target )
-{
-  bool validTarget = true;
-
-  if( &actor == &target )
-  {
-    DALI_LOG_WARNING( "Source actor and target actor can not be the same, Sibling order not changed.\n" );
-    validTarget = false;
-  }
-  else if( actor.GetParent() != target.GetParent() )
-  {
-    DALI_LOG_WARNING( "Source actor and target actor need to have common parent, Sibling order not changed.\n" );
-    validTarget = false;
-  }
-
-  return validTarget;
-}
-
 } // unnamed namespace
 
 /**
@@ -2112,7 +2086,6 @@ Actor::Actor( DerivedType derivedType )
   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
   mSortedDepth( 0u ),
   mDepth( 0u ),
-  mSiblingOrder(0u),
   mIsRoot( ROOT_LAYER == derivedType ),
   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
   mIsOnStage( false ),
@@ -2383,203 +2356,42 @@ bool Actor::IsNodeConnected() const
   return connected;
 }
 
-// This method generates the depth tree using the recursive function below,
-// then walks the tree and sets a depth index based on traversal order. It
-// sends a single message to update manager to update all the actor's nodes in this
-// tree with the depth index. The sceneGraphNodeDepths vector's elements are ordered
-// by depth, and could be used to reduce sorting in the update thread.
+// This method initiates traversal of the actor tree using depth-first
+// traversal to set a depth index based on traversal order. It sends a
+// single message to update manager to update all the actor's nodes in
+// this tree with the depth index. The sceneGraphNodeDepths vector's
+// elements are ordered by depth, and could be used to reduce sorting
+// in the update thread.
 void Actor::RebuildDepthTree()
 {
   DALI_LOG_TIMER_START(depthTimer);
 
-  DepthNodeMemoryPool nodeMemoryPool;
-  ActorDepthTreeNode* rootNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( this, mSiblingOrder );
-
-  int actorCount = BuildDepthTree( nodeMemoryPool, rootNode );
-
   // Vector of scene-graph nodes and their depths to send to UpdateManager
   // in a single message
-  OwnerPointer< SceneGraph::NodeDepths > sceneGraphNodeDepths = new SceneGraph::NodeDepths(actorCount);
-
-  // Traverse depth tree and set mSortedDepth on each actor and scenegraph node
-  uint32_t sortOrder = 1u; // Don't start at zero, as visual depth can be negative
-  ActorDepthTreeNode* currentNode = rootNode;
-  bool firstVisit = true;
-  while( currentNode != rootNode || firstVisit)
-  {
-    firstVisit = false;
-
-    // Visit node, performing action
-    for( std::vector<Actor*>::iterator iter = currentNode->mActors.begin(); iter != currentNode->mActors.end(); ++iter )
-    {
-      (*iter)->mSortedDepth = sortOrder * DevelLayer::SIBLING_ORDER_MULTIPLIER;
-      sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>((*iter)->mNode), (*iter)->mSortedDepth );
-    }
-    ++sortOrder;
-
-    // Descend tree
-    if( currentNode->mFirstChildNode )
-    {
-      currentNode = currentNode->mFirstChildNode;
-    }
-    else // leaf node, goto next sibling, or return up tree.
-    {
-      bool breakout=false;
-      while( ! currentNode->mNextSiblingNode )
-      {
-        if( currentNode == rootNode ) // If we get to root of tree, stop
-        {
-          breakout = true;
-          break;
-        }
-        currentNode = currentNode->mParentNode;
-      }
+  OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
 
-      if( breakout )
-      {
-        break;
-      }
-      currentNode = currentNode->mNextSiblingNode;
-    }
-  }
+  int depthIndex = 1;
+  DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
 
   SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
-  DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree create time: ");
+  DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
 }
 
-/**
- * Structure to store the actor's associated node in the depth tree for child
- * traversal
- */
-struct ActorNodePair
+void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
 {
-  Actor* actor;
-  ActorDepthTreeNode* node;
-  ActorNodePair( Actor* actor, ActorDepthTreeNode* node )
-  : actor(actor),
-    node(node)
-  {
-  }
-};
-
-/*
- * Descend actor tree, building a depth tree based on actor's sibling order.
- * Actors with the same sibling order share the same depth tree. Siblings
- * in the depth tree are ordered by actor's sibling order.
- *
- * An actor tree like this:
- *
- *                  Root (SO:0)
- *                 _/    |   \_
- *               _/      |     \_
- *             _/        |       \_
- *            /          |         \
- *        A(SO:1)     B(SO:2)    C(SO:1)
- *         _/\_          |         _/ \_
- *        /    \         |       /       \
- *     D(SO:0) E(SO:0) F(SO:0) G(SO:1)  H(SO:0)
- *
- * will end up as a depth tree like this:
- *
- *     RootNode [ Root ] -> NULL
- *       |(mFC)
- *       V                (mNS)
- *     Node [ A, C ] ------------------------>  Node [ B ] -> NULL
- *       |                                        |
- *       V                                        V
- *     Node [ D, E, H ] -> Node [ G ] -> NULL   Node [ F ] -> NULL
- *       |                   |                    |
- *       V                   V                    V
- *     NULL                NULL                 NULL
- *
- * (All nodes also point to their parents to enable storage free traversal)
- */
-int Actor::BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* node )
-{
-  int treeCount=1; // Count self and children
+  mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
+  sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
 
   // Create/add to children of this node
   if( mChildren )
   {
-    std::vector<ActorNodePair> storedChildren;
-    storedChildren.reserve( mChildren->size() );
-
     for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
     {
       Actor* childActor = (*it).Get();
-      if( childActor->IsLayer() )
-      {
-        Layer* layer = static_cast<Layer*>(childActor);
-        if( layer->GetBehavior() == Dali::Layer::LAYER_3D )
-        {
-          // Ignore this actor and children.
-          continue;
-        }
-      }
-
-      // If no existing depth node children
-      if( node->mFirstChildNode == NULL )
-      {
-        node->mFirstChildNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
-        node->mFirstChildNode->mParentNode = node;
-        storedChildren.push_back(ActorNodePair( childActor, node->mFirstChildNode ));
-      }
-      else // find child node with matching sibling order (insertion sort)
-      {
-        bool addedChildActor = false;
-
-        // depth tree child nodes ordered by sibling order
-        ActorDepthTreeNode* lastNode = NULL;
-        for( ActorDepthTreeNode* childNode = node->mFirstChildNode; childNode != NULL; childNode = childNode->mNextSiblingNode )
-        {
-          uint16_t actorSiblingOrder = childActor->mSiblingOrder;
-          uint16_t currentSiblingOrder = childNode->GetSiblingOrder();
-
-          if( actorSiblingOrder == currentSiblingOrder )
-          {
-            // Don't need a new depth node, add to existing node
-            childNode->AddActor( childActor );
-            storedChildren.push_back(ActorNodePair( childActor, childNode ));
-            addedChildActor = true;
-            break;
-          }
-          else if( actorSiblingOrder < currentSiblingOrder )
-          {
-            break;
-          }
-          lastNode = childNode;
-        }
-
-        // No matching sibling order - create new node and insert into sibling list
-        if( !addedChildActor )
-        {
-          ActorDepthTreeNode* newNode = new (nodeMemoryPool.AllocateRaw()) ActorDepthTreeNode( childActor, childActor->mSiblingOrder );
-
-          newNode->mParentNode = node;
-          storedChildren.push_back(ActorNodePair( childActor, newNode ));
-
-          if( lastNode == NULL ) // Insert at start of siblings
-          {
-            ActorDepthTreeNode* nextNode = node->mFirstChildNode;
-            node->mFirstChildNode = newNode;
-            newNode->mNextSiblingNode = nextNode;
-          }
-          else // insert into siblings after last node
-          {
-            newNode->mNextSiblingNode = lastNode->mNextSiblingNode;
-            lastNode->mNextSiblingNode = newNode;
-          }
-        }
-      }
-    }
-
-    // Order of descent doesn't matter; we're using insertion to sort.
-    for( std::vector<ActorNodePair>::iterator iter = storedChildren.begin(); iter != storedChildren.end(); ++iter )
-    {
-      treeCount += iter->actor->BuildDepthTree( nodeMemoryPool, iter->node );
+      ++depthIndex;
+      childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
     }
   }
-  return treeCount;
 }
 
 unsigned int Actor::GetDefaultPropertyCount() const
@@ -3015,10 +2827,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
 
       if( property.Get( value ) )
       {
-        if( static_cast<unsigned int>(value) != mSiblingOrder )
-        {
-          SetSiblingOrder( value );
-        }
+        SetSiblingOrder( value );
       }
       break;
     }
@@ -4277,7 +4086,7 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
 
     case Dali::DevelActor::Property::SIBLING_ORDER:
     {
-      value = static_cast<int>(mSiblingOrder);
+      value = static_cast<int>( GetSiblingOrder() );
       break;
     }
 
@@ -5248,192 +5057,88 @@ void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
 
 void Actor::SetSiblingOrder( unsigned int order )
 {
-  mSiblingOrder = std::min( order, static_cast<unsigned int>( DevelLayer::SIBLING_ORDER_MULTIPLIER ) );
-
-  if( mIsOnStage )
-  {
-    StagePtr stage = Stage::GetCurrent();
-    if( stage )
-    {
-      stage->RequestRebuildDepthTree();
-    }
-  }
-}
-
-void Actor::DefragmentSiblingIndexes( ActorContainer& siblings )
-{
-  // Sibling index may not be in consecutive order as the sibling range is limited ( DevelLayer::SIBLING_ORDER_MULTIPLIER )
-  // we need to remove the gaps and ensure the number start from 0 and consecutive hence have a full range.
-
-  // Start at index 0, while index <= highest order
-  // Find next index higher than 0
-  //   if nextHigher > index+1
-  //      set all nextHigher orders to index+1
-
-  // Limitation: May reach the ceiling of DevelLayer::SIBLING_ORDER_MULTIPLIER with highest sibling.
-
-  ActorIter end = siblings.end();
-  int highestOrder = 0;
-  for( ActorIter iter = siblings.begin(); iter != end; ++iter )
-  {
-    ActorPtr sibling = (*iter);
-    int siblingOrder = sibling->mSiblingOrder;
-    highestOrder = std::max( highestOrder, siblingOrder );
-  }
-
-  for ( int index = 0; index <= highestOrder; index++ )
+  if ( mParent )
   {
-    int nextHighest = -1;
+    ActorContainer& siblings = *(mParent->mChildren);
+    unsigned int currentOrder = GetSiblingOrder();
 
-    // Find Next highest
-    for( ActorIter iter = siblings.begin(); iter != end; ++iter )
+    if( order != currentOrder )
     {
-      ActorPtr sibling = (*iter);
-      int siblingOrder = sibling->mSiblingOrder;
-
-      if ( siblingOrder > index )
+      if( order == 0 )
+      {
+        LowerToBottom();
+      }
+      else if( order < siblings.size() -1 )
       {
-        if ( nextHighest == -1 )
+        if( order > currentOrder )
         {
-          nextHighest = siblingOrder;
+          RaiseAbove( *siblings[order] );
+        }
+        else
+        {
+          LowerBelow( *siblings[order] );
         }
-        nextHighest = std::min( nextHighest, siblingOrder );
+      }
+      else
+      {
+        RaiseToTop();
       }
     }
+  }
+}
+
+unsigned int Actor::GetSiblingOrder() const
+{
+  unsigned int order = 0;
 
-    // Check if a gap exists between indexes, if so set next index to consecutive number
-    if ( ( nextHighest - index ) > 1 )
+  if ( mParent )
+  {
+    ActorContainer& siblings = *(mParent->mChildren);
+    for( size_t i=0; i<siblings.size(); ++i )
     {
-      for( ActorIter iter = siblings.begin(); iter != end; ++iter )
+      if( siblings[i] == this )
       {
-        ActorPtr sibling = (*iter);
-        int siblingOrder = sibling->mSiblingOrder;
-        if ( siblingOrder == nextHighest )
-        {
-          sibling->mSiblingOrder =  index + 1;
-          if ( sibling->mSiblingOrder >= Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER )
-          {
-            DALI_LOG_WARNING( "Reached max sibling order level for raising / lowering actors\n" );
-            sibling->mSiblingOrder = Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER;
-          }
-          sibling->SetSiblingOrder( sibling->mSiblingOrder );
-        }
+        order = i;
+        break;
       }
     }
   }
+
+  return order;
 }
 
-bool Actor::ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom )
+void Actor::RequestRebuildDepthTree()
 {
-  // Allows exclusive levels for an actor by shifting all sibling levels at the target and above by 1
-  bool defragmentationRequired( false );
-  ActorIter end = siblings.end();
-  for( ActorIter iter = siblings.begin(); ( iter != end ) ; ++iter )
+  if( mIsOnStage )
   {
-    // Move actors at nearest order and above up by 1
-    ActorPtr sibling = (*iter);
-    if ( sibling != this )
+    StagePtr stage = Stage::GetCurrent();
+    if( stage )
     {
-      // Iterate through container of actors, any actor with a sibling order of the target or greater should
-      // be incremented by 1.
-      if ( sibling->mSiblingOrder >= targetLevelToShiftFrom )
-      {
-        sibling->mSiblingOrder++;
-        if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
-        {
-          // If a sibling order raises so that it is only 1 from the maximum allowed then set flag so
-          // can re-order all sibling orders.
-          defragmentationRequired = true;
-        }
-        sibling->SetSiblingOrder( sibling->mSiblingOrder );
-      }
+      stage->RequestRebuildDepthTree();
     }
   }
-  return defragmentationRequired;
 }
 
 void Actor::Raise()
 {
-  /*
-     1) Check if already at top and nothing to be done.
-        This Actor can have highest sibling order but if not exclusive then another actor at same sibling
-        order can be positioned above it due to insertion order of actors.
-     2) Find nearest sibling level above, these are the siblings this actor needs to be above
-     3) a) There may be other levels above this target level
-        b) Increment all sibling levels at the level above nearest(target)
-        c) Now have a vacant sibling level
-     4) Set this actor's sibling level to nearest +1 as now vacated.
-
-     Note May not just be sibling level + 1 as could be empty levels in-between
-
-     Example:
-
-     1 ) Initial order
-        ActorC ( sibling level 4 )
-        ActorB ( sibling level 3 )
-        ActorA ( sibling level 1 )
-
-     2 )  ACTION: Raise A above B
-        a) Find nearest level above A = Level 3
-        b) Increment levels above Level 3
-
-           ActorC ( sibling level 5 )
-           ActorB ( sibling level 3 )  NEAREST
-           ActorA ( sibling level 1 )
-
-     3 ) Set Actor A sibling level to nearest +1 as vacant
-
-         ActorC ( sibling level 5 )
-         ActorA ( sibling level 4 )
-         ActorB ( sibling level 3 )
-
-     4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-         If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-         remove any empty sibling order gaps and start from sibling level 0 again.
-         If the number of actors reaches this maximum and all using exclusive sibling order values then
-         defragmention will stop and new sibling orders will be set to same max value.
-  */
   if ( mParent )
   {
-    int nearestLevel = mSiblingOrder;
-    int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER;
-    bool defragmentationRequired( false );
-
-    ActorContainer* siblings = mParent->mChildren;
-
-    // Find Nearest sibling level above this actor
-    ActorIter end = siblings->end();
-    for( ActorIter iter = siblings->begin(); iter != end; ++iter )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this ) // If not already at end
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      for( size_t i=0; i<siblings.size(); ++i )
       {
-        int order = GetSiblingOrder( sibling );
-
-        if ( ( order >= mSiblingOrder ) )
+        if( siblings[i] == this )
         {
-          int distanceToNextLevel =  order - mSiblingOrder;
-          if ( distanceToNextLevel < shortestDistanceToNextLevel )
-          {
-            nearestLevel = order;
-            shortestDistanceToNextLevel = distanceToNextLevel;
-          }
+          // Swap with next
+          ActorPtr next = siblings[i+1];
+          siblings[i+1] = this;
+          siblings[i] = next;
+          break;
         }
       }
     }
-
-    if ( nearestLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at top
-    {
-      mSiblingOrder = nearestLevel + 1; // Set sibling level to that above the nearest level
-      defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
-      // Move current actor to newly vacated order level
-      SetSiblingOrder( mSiblingOrder );
-      if ( defragmentationRequired )
-      {
-        DefragmentSiblingIndexes( *siblings );
-      }
-    }
-    SetSiblingOrder( mSiblingOrder );
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5443,63 +5148,24 @@ void Actor::Raise()
 
 void Actor::Lower()
 {
-  /**
-    1) Check if actor already at bottom and if nothing needs to be done
-       This Actor can have lowest sibling order but if not exclusive then another actor at same sibling
-       order can be positioned above it due to insertion order of actors so need to move this actor below it.
-    2) Find nearest sibling level below, this Actor needs to be below it
-    3) a) Need to vacate a sibling level below nearest for this actor to occupy
-       b) Shift up all sibling order values of actor at the nearest level and levels above it to vacate a level.
-       c) Set this actor's sibling level to this newly vacated level.
-    4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-       If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-       remove any empty sibling order gaps and start from sibling level 0 again.
-       If the number of actors reaches this maximum and all using exclusive sibling order values then
-       defragmention will stop and new sibling orders will be set to same max value.
-  */
-
   if ( mParent )
   {
-    // 1) Find nearest level below
-    int nearestLevel = mSiblingOrder;
-    int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER;
-
-    ActorContainer* siblings = mParent->mChildren;
-
-    ActorIter end = siblings->end();
-    for( ActorIter iter = siblings->begin(); iter != end; ++iter )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this ) // If not already at beginning
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      for( size_t i=0; i<siblings.size(); ++i )
       {
-        int order = GetSiblingOrder( sibling );
-
-        if ( order <= mSiblingOrder )
+        if( siblings[i] == this )
         {
-          int distanceToNextLevel =  mSiblingOrder - order;
-          if ( distanceToNextLevel < shortestDistanceToNextLevel )
-          {
-            nearestLevel = order;
-            shortestDistanceToNextLevel = distanceToNextLevel;
-          }
+          // Swap with previous
+          ActorPtr previous = siblings[i-1];
+          siblings[i-1] = this;
+          siblings[i] = previous;
+          break;
         }
       }
     }
-
-    bool defragmentationRequired ( false );
-
-    // 2) If actor already not at bottom, raise all actors at required level and above
-    if ( shortestDistanceToNextLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at bottom
-    {
-      mSiblingOrder = nearestLevel;
-      defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
-      // Move current actor to newly vacated order
-      SetSiblingOrder( mSiblingOrder );
-      if ( defragmentationRequired )
-      {
-        DefragmentSiblingIndexes( *siblings );
-      }
-    }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5509,50 +5175,19 @@ void Actor::Lower()
 
 void Actor::RaiseToTop()
 {
-  /**
-    1 ) Find highest sibling order actor
-    2 ) If highest sibling level not itself then set sibling order to that + 1
-    3 ) highest sibling order can be same as itself so need to increment over that
-    4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-        If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-        remove any empty sibling order gaps and start from sibling level 0 again.
-        If the number of actors reaches this maximum and all using exclusive sibling order values then
-        defragmention will stop and new sibling orders will be set to same max value.
-   */
-
   if ( mParent )
   {
-    int maxOrder = 0;
-
-    ActorContainer* siblings = mParent->mChildren;
-
-    ActorIter end = siblings->end();
-    for( ActorIter iter = siblings->begin(); iter != end; ++iter )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this ) // If not already at end
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
+      if( iter != siblings.end() )
       {
-        maxOrder = std::max( GetSiblingOrder( sibling ), maxOrder );
+        siblings.erase(iter);
+        siblings.push_back(ActorPtr(this));
       }
     }
-
-    bool defragmentationRequired( false );
-
-    if ( maxOrder >= mSiblingOrder )
-    {
-      mSiblingOrder = maxOrder + 1;
-      if ( mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
-      {
-        defragmentationRequired = true;
-      }
-    }
-
-    SetSiblingOrder( mSiblingOrder );
-
-    if ( defragmentationRequired )
-    {
-      DefragmentSiblingIndexes( *siblings );
-    }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5562,62 +5197,21 @@ void Actor::RaiseToTop()
 
 void Actor::LowerToBottom()
 {
-  /**
-    See Actor::LowerToBottom()
-
-    1 ) Check if this actor already at exclusively at the bottom, if so then no more to be done.
-    2 ) a ) Check if the bottom position 0 is vacant.
-        b ) If 0 position is not vacant then shift up all sibling order values from 0 and above
-        c ) 0 sibling position is vacant.
-    3 ) Set this actor to vacant sibling order 0;
-    4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-        If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-        remove any empty sibling order gaps and start from sibling level 0 again.
-        If the number of actors reaches this maximum and all using exclusive sibling order values then
-        defragmention will stop and new sibling orders will be set to same max value.
-   */
-
   if ( mParent )
   {
-    bool defragmentationRequired( false );
-    bool orderZeroFree ( true );
-
-    ActorContainer* siblings = mParent->mChildren;
-
-    bool actorAtLowestOrder = true;
-    ActorIter end = siblings->end();
-    for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this ) // If not already at bottom,
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
-      {
-        int siblingOrder = GetSiblingOrder( sibling );
-        if ( siblingOrder <= mSiblingOrder )
-        {
-          actorAtLowestOrder = false;
-        }
-
-        if ( siblingOrder == 0 )
-        {
-          orderZeroFree = false;
-        }
-      }
-    }
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-    if ( ! actorAtLowestOrder  )
-    {
-      if ( ! orderZeroFree )
-      {
-        defragmentationRequired = ShiftSiblingsLevels( *siblings, 0 );
-      }
-      mSiblingOrder = 0;
-      SetSiblingOrder( mSiblingOrder );
-
-      if ( defragmentationRequired )
+      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
+      if( iter != siblings.end() )
       {
-        DefragmentSiblingIndexes( *siblings );
+        siblings.erase(iter);
+        siblings.insert(siblings.begin(), thisPtr);
       }
     }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5627,36 +5221,25 @@ void Actor::LowerToBottom()
 
 void Actor::RaiseAbove( Internal::Actor& target )
 {
-  /**
-    1 ) a) Find target actor's sibling order
-        b) If sibling order of target is the same as this actor then need to this Actor's sibling order
-           needs to be above it or the insertion order will determine which is drawn on top.
-    2 ) Shift up by 1 all sibling order greater than target sibling order
-    3 ) Set this actor to the sibling order to target +1 as will be a newly vacated gap above
-    4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-        If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-        remove any empty sibling order gaps and start from sibling level 0 again.
-        If the number of actors reaches this maximum and all using exclusive sibling order values then
-        defragmention will stop and new sibling orders will be set to same max value.
-   */
-
   if ( mParent )
   {
-    if ( ValidateActors( *this, target ) )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this && target.mParent == mParent ) // If not already at top
     {
-       // Find target's sibling order
-       // Set actor sibling order to this number +1
-      int targetSiblingOrder = GetSiblingOrder( &target );
-      ActorContainer* siblings = mParent->mChildren;
-      mSiblingOrder = targetSiblingOrder + 1;
-      bool defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder );
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-      SetSiblingOrder( mSiblingOrder );
-
-      if ( defragmentationRequired )
+      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
+      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
+      if( thisIter < targetIter )
       {
-        DefragmentSiblingIndexes( *(mParent->mChildren) );
+        siblings.erase(thisIter);
+        // Erasing early invalidates the targetIter. (Conversely, inserting first may also
+        // invalidate thisIter)
+        targetIter = std::find( siblings.begin(), siblings.end(), &target );
+        ++targetIter;
+        siblings.insert(targetIter, thisPtr);
       }
+      RequestRebuildDepthTree();
     }
   }
   else
@@ -5667,59 +5250,22 @@ void Actor::RaiseAbove( Internal::Actor& target )
 
 void Actor::LowerBelow( Internal::Actor& target )
 {
-  /**
-     1 ) a) Find target actor's sibling order
-         b) If sibling order of target is the same as this actor then need to this Actor's sibling order
-            needs to be below it or the insertion order will determine which is drawn on top.
-     2 ) Shift the target sibling order and all sibling orders at that level or above by 1
-     3 ) Set this actor to the sibling order of the target before it changed.
-     4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER
-         If shifting causes this ceiling to be reached. then a defragmentation can be performed to
-         remove any empty sibling order gaps and start from sibling level 0 again.
-         If the number of actors reaches this maximum and all using exclusive sibling order values then
-         defragmention will stop and new sibling orders will be set to same max value.
-   */
-
   if ( mParent )
   {
-    if ( ValidateActors( *this, target )  )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
     {
-      bool defragmentationRequired ( false );
-      // Find target's sibling order
-      // Set actor sibling order to target sibling order - 1
-      int targetSiblingOrder = GetSiblingOrder( &target);
-      ActorContainer* siblings = mParent->mChildren;
-      if ( targetSiblingOrder == 0 )
-      {
-        //lower to botton
-        ActorIter end = siblings->end();
-        for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter )
-        {
-          ActorPtr sibling = (*iter);
-          if ( sibling != this )
-          {
-            sibling->mSiblingOrder++;
-            if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
-            {
-              defragmentationRequired = true;
-            }
-            sibling->SetSiblingOrder( sibling->mSiblingOrder );
-          }
-        }
-        mSiblingOrder = 0;
-      }
-      else
-      {
-        defragmentationRequired = ShiftSiblingsLevels( *siblings, targetSiblingOrder );
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-        mSiblingOrder = targetSiblingOrder;
-      }
-      SetSiblingOrder( mSiblingOrder );
+      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
+      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
 
-      if ( defragmentationRequired )
+      if( thisIter > targetIter )
       {
-        DefragmentSiblingIndexes( *(mParent->mChildren) );
+        siblings.erase(thisIter); // this only invalidates iterators at or after this point.
+        siblings.insert(targetIter, thisPtr);
       }
+      RequestRebuildDepthTree();
     }
   }
   else
index b7e177dba66da28f6da3d6b788ab0ad820362118..d931353c0f5bd5469c63d348c3eea05c56b4876a 100644 (file)
@@ -36,6 +36,7 @@
 #include <dali/internal/event/common/stage-def.h>
 #include <dali/internal/event/rendering/renderer-impl.h>
 #include <dali/internal/update/nodes/node-declarations.h>
+#include <dali/internal/update/manager/update-manager.h>
 
 namespace Dali
 {
@@ -1581,13 +1582,10 @@ protected:
 
   /**
    * Traverse the actor tree, inserting actors into the depth tree in sibling order.
-   * For all actors that share a sibling order, they also share a depth tree, for
-   * optimal render performance.
-   * @param[in] nodeMemoryPool The memory pool used to allocate depth nodes
-   * @param[in,out] depthTreeNode The depth tree node to which to add this actor's children
-   * @return The count of actors in this depth tree
+   * @param[in] sceneGraphNodeDepths A vector capturing the nodes and their depth index
+   * @param[in,out] depthIndex The current depth index (traversal index)
    */
-  int BuildDepthTree( DepthNodeMemoryPool& nodeMemoryPool, ActorDepthTreeNode* depthTreeNode );
+  void DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex );
 
 public:
 
@@ -1881,26 +1879,21 @@ private:
 
   /**
    * Set Sibling order
-   * @param[in] order The sibling order this Actor should be
+   * @param[in] order The sibling order this Actor should be. It will place
+   * the actor at this index in it's parent's child array.
    */
   void SetSiblingOrder( unsigned int order);
 
   /**
-   * @brief Re-orders the sibling order when any actor raised to the max level
-   * @param[in] siblings the container of sibling actors
+   * Get Sibling order
+   * @return the order of this actor amongst it's siblings
    */
-  void DefragmentSiblingIndexes( ActorContainer& siblings );
+  unsigned int GetSiblingOrder() const;
 
   /**
-   * @brief Shifts all siblings levels from the target level up by 1 to make space for a newly insert sibling
-   * at an exclusive level.
-   *
-   * @note Used with Raise and Lower API
-   *
-   * @param[in] siblings the actor container of the siblings
-   * @param[in] targetLevelToShiftFrom the sibling level to start shifting from
+   * Request that the stage rebuilds the actor depth indices.
    */
-  bool ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom );
+  void RequestRebuildDepthTree();
 
   /**
    * @brief Get the current position of the actor in screen coordinates.
@@ -1952,7 +1945,7 @@ protected:
 
   uint32_t mSortedDepth;      ///< The sorted depth index. A combination of tree traversal and sibling order.
   uint16_t mDepth;            ///< The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
-  uint16_t mSiblingOrder;     ///< The sibling order of the actor
+
 
   const bool mIsRoot                               : 1; ///< Flag to identify the root actor
   const bool mIsLayer                              : 1; ///< Flag to identify that this is a layer
@@ -1981,67 +1974,6 @@ private:
   static unsigned int mActorCounter;    ///< A counter to track the actor instance creation
 };
 
-/**
- * Helper class to create sorted depth index
- */
-class ActorDepthTreeNode
-{
-public:
-  ActorDepthTreeNode()
-  : mParentNode(NULL),
-    mNextSiblingNode(NULL),
-    mFirstChildNode(NULL),
-    mSiblingOrder( 0 )
-  {
-  }
-
-  ActorDepthTreeNode( Actor* actor, uint16_t siblingOrder )
-  : mParentNode(NULL),
-    mNextSiblingNode(NULL),
-    mFirstChildNode(NULL),
-    mSiblingOrder( siblingOrder )
-  {
-    mActors.push_back( actor );
-  }
-
-  ~ActorDepthTreeNode()
-  {
-    if( mFirstChildNode )
-    {
-      delete mFirstChildNode;
-      mFirstChildNode = NULL;
-    }
-    if( mNextSiblingNode )
-    {
-      delete mNextSiblingNode;
-      mNextSiblingNode = NULL;
-    }
-    mParentNode = NULL;
-  }
-
-  uint16_t GetSiblingOrder()
-  {
-    return mSiblingOrder;
-  }
-
-  void AddActor( Actor* actor )
-  {
-    mActors.push_back( actor );
-  }
-
-public:
-  std::vector<Actor*> mActors; // Array of actors with the same sibling order and same ancestor sibling orders
-  ActorDepthTreeNode* mParentNode;
-  ActorDepthTreeNode* mNextSiblingNode;
-  ActorDepthTreeNode* mFirstChildNode;
-  uint16_t mSiblingOrder;
-
-private:
-  ActorDepthTreeNode( ActorDepthTreeNode& );
-  ActorDepthTreeNode& operator=(const ActorDepthTreeNode& );
-};
-
-
 } // namespace Internal
 
 // Helpers for public-api forwarding methods
index 704b25c7fd9eeb21cc280638de2fbf125f439bec..d057d6cc7ca61a10d9f8dac76c4e2074a2dcea6b 100644 (file)
@@ -90,9 +90,8 @@ struct NodeDepthPair
 
 struct NodeDepths
 {
-  NodeDepths( int reserveSize )
+  NodeDepths()
   {
-    nodeDepths.reserve(reserveSize);
   }
 
   void Add( SceneGraph::Node* node, uint32_t sortedDepth )