Changed draw ordering to take into account the depth of the node in the hierarchy 05/43505/8
authorFerran Sole <ferran.sole@samsung.com>
Thu, 9 Jul 2015 15:37:43 +0000 (16:37 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Tue, 14 Jul 2015 09:49:04 +0000 (10:49 +0100)
Tree depth is multiplied by a known factor (10.000) to make it dominate the ordering.
Allows controls to still put renderers on top of their children as long as they know
the depth of the child tree

Change-Id: I3793b036150d39a930e9c55da1ea5b16febfd571

dali/internal/event/actors/actor-impl.h
dali/internal/event/events/hit-test-algorithm-impl.cpp
dali/internal/update/manager/prepare-render-instructions.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/actors/layer.h

index d601a20..afaa5c7 100644 (file)
@@ -1813,7 +1813,7 @@ protected:
   std::string     mName;      ///< Name of the actor
   unsigned int    mId;        ///< A unique ID to identify the actor starting from 1, and 0 is reserved
 
-  unsigned short mDepth                            :12; ///< The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
+  unsigned short mDepth                            :12; ///< Cached: The depth in the hierarchy of the actor. Only 4096 levels of depth are supported
   const bool mIsRoot                               : 1; ///< Flag to identify the root actor
   const bool mIsRenderable                         : 1; ///< Flag to identify that this is a renderable actor
   const bool mIsLayer                              : 1; ///< Flag to identify that this is a layer
index 9d2f4ab..50457c2 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/system-overlay.h>
+#include <dali/public-api/actors/layer.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector4.h>
 #include <dali/integration-api/debug.h>
@@ -169,7 +170,8 @@ HitActor HitTestWithinLayer( Actor& actor,
                              HitTestInterface& hitCheck,
                              bool& stencilOnLayer,
                              bool& stencilHit,
-                             bool parentIsStencil )
+                             bool parentIsStencil,
+                             bool layerIs3d )
 {
   HitActor hit;
 
@@ -224,7 +226,7 @@ HitActor HitTestWithinLayer( Actor& actor,
             {
               if ( actor.GetRendererCount() )
               {
-                hit.depth = actor.GetRendererAt( 0 ).GetDepthIndex();
+                hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER + actor.GetRendererAt( 0 ).GetDepthIndex();
               }
               else
               {
@@ -270,7 +272,8 @@ HitActor HitTestWithinLayer( Actor& actor,
                                                   hitCheck,
                                                   stencilOnLayer,
                                                   stencilHit,
-                                                  isStencil ) );
+                                                  isStencil,
+                                                  layerIs3d) );
 
         bool updateChildHit = false;
         // If our ray casting hit, then check then if the hit actor's depth is greater that the favorite, it will be preferred
@@ -281,8 +284,8 @@ HitActor HitTestWithinLayer( Actor& actor,
             updateChildHit = true;
           }
 
-          // If the hit actor's depth is equal to current favorite, then we check the distance and prefer the closer
-          else if ( currentHit.depth == childHit.depth )
+          // In a 3D layer, if the hit actor's depth is equal to current favorite, then we check the distance and prefer the closer
+          else if ( layerIs3d && currentHit.depth == childHit.depth )
           {
             if ( currentHit.distance < childHit.distance )
             {
@@ -294,7 +297,7 @@ HitActor HitTestWithinLayer( Actor& actor,
         if ( updateChildHit )
         {
           if( !parentIsRenderable || currentHit.depth > hit.depth ||
-            ( currentHit.depth == hit.depth && currentHit.distance < hit.distance ) )
+            ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) )
             {
               childHit = currentHit;
             }
@@ -456,7 +459,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         hitCheck,
                                         stencilOnLayer,
                                         stencilHit,
-                                        false );
+                                        false,
+                                        layer->GetBehavior() == Dali::Layer::LAYER_3D);
             }
             else if ( IsWithinSourceActors( *sourceActor, *layer ) )
             {
@@ -471,7 +475,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         hitCheck,
                                         stencilOnLayer,
                                         stencilHit,
-                                        false );
+                                        false,
+                                        layer->GetBehavior() == Dali::Layer::LAYER_3D);
             }
 
             // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable
index bab7f46..b59a409 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/actors/layer.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/layer-impl.h> // for the default sorting function
 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
@@ -205,7 +206,7 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
     RenderItem& item = renderList.GetNextFreeItem();
     const Renderer& renderer = renderable.GetRenderer();
     item.SetRenderer( const_cast< Renderer* >( &renderer ) );
-    item.SetDepthIndex( renderable.GetDepthIndex() );
+    item.SetDepthIndex( renderable.GetDepthIndex() + static_cast<int>( parentNode.GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER );
 
     // save MV matrix onto the item
     Matrix& modelViewMatrix = item.GetModelViewMatrix();
@@ -308,8 +309,8 @@ bool CompareItems( const RendererWithSortAttributes& lhs, const RendererWithSort
   return lhs.renderItem->GetDepthIndex() < rhs.renderItem->GetDepthIndex();
 }
 /**
- * Function which sorts the render items by depth index then by Z function,
- * then by instance ptrs of shader/geometry/material.
+ * Function which sorts the render items by Z function, then
+ * by instance ptrs of shader/geometry/material.
  * @param lhs item
  * @param rhs item
  * @return true if left item is greater than right
@@ -319,23 +320,19 @@ bool CompareItemsWithZValue( const RendererWithSortAttributes& lhs, const Render
   // @todo MESH_REWORK Consider replacing all these sortAttributes with a single long int that
   // encapsulates the same data (e.g. the middle-order bits of the ptrs)
 
-  if( lhs.renderItem->GetDepthIndex() == rhs.renderItem->GetDepthIndex() )
+  if( Equals(lhs.zValue, rhs.zValue) )
   {
-    if( Equals(lhs.zValue, rhs.zValue) )
+    if( lhs.shader == rhs.shader )
     {
-      if( lhs.shader == rhs.shader )
+      if( lhs.material == rhs.material )
       {
-        if( lhs.material == rhs.material )
-        {
-          return lhs.geometry < rhs.geometry;
-        }
-        return lhs.material < rhs.material;
+        return lhs.geometry < rhs.geometry;
       }
-      return lhs.shader < rhs.shader;;
+      return lhs.material < rhs.material;
     }
-    return lhs.zValue > rhs.zValue;
+    return lhs.shader < rhs.shader;
   }
-  return lhs.renderItem->GetDepthIndex() < rhs.renderItem->GetDepthIndex();
+  return lhs.zValue > rhs.zValue;
 }
 
 inline void SortOpaqueRenderItems(
@@ -494,8 +491,16 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
     }
   }
 
-  // sort the renderers back to front, Z Axis point from near plane to far plane
-  std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItemsWithZValue );
+  if( layer.GetBehavior() ==  Dali::Layer::LAYER_3D)
+  {
+    // sort the renderers back to front, Z Axis point from near plane to far plane
+    std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItemsWithZValue );
+  }
+  else
+  {
+    // sort the renderers based on DepthIndex
+    std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems );
+  }
 
   // reorder/repopulate the renderitems in renderlist to correct order based on sortinghelper
   DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n");
index 225c1d8..db5798f 100644 (file)
@@ -59,6 +59,7 @@ Node::Node()
   mExclusiveRenderTask( NULL ),
   mAttachment( NULL ),
   mChildren(),
+  mDepth(0u),
   mDirtyFlags(AllFlags),
   mIsRoot( false ),
   mInheritOrientation( true ),
@@ -249,6 +250,7 @@ void Node::SetParent(Node& parentNode)
   DALI_ASSERT_ALWAYS(mParent == NULL);
 
   mParent = &parentNode;
+  mDepth = mParent->GetDepth() + 1u;
 }
 
 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
@@ -267,6 +269,7 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std
 
   // Remove back-pointer to parent
   mParent = NULL;
+  mDepth = 0u;
 
   // Remove all child pointers
   mChildren.Clear();
index b8da325..7c4242b 100644 (file)
@@ -921,6 +921,11 @@ public:
     return mInhibitLocalTransform;
   }
 
+  unsigned short GetDepth() const
+  {
+    return mDepth;
+  }
+
 protected:
 
   /**
@@ -1010,7 +1015,8 @@ protected:
 
 
   // flags, compressed to bitfield
-  int  mDirtyFlags:10;                               ///< A composite set of flags for each of the Node properties
+  unsigned short mDepth: 12;                        ///< Depth in the hierarchy
+  int  mDirtyFlags:8;                               ///< A composite set of flags for each of the Node properties
 
   bool mIsRoot:1;                                    ///< True if the node cannot have a parent
   bool mInheritOrientation:1;                        ///< Whether the parent's orientation should be inherited.
index 33905cf..036c79c 100644 (file)
@@ -104,6 +104,15 @@ public:
     LAYER_3D,
   };
 
+  /*
+   * TREE_DEPTH_MULTIPLIER is used by the rendering sorting algorithm to decide which actors to render first.
+   * For 2D layers, this value will be multiplied to the actor depth in the tree and added to the depth index
+   * to obtain the value which will be used for ordering
+   */
+  enum TreeDepthMultiplier
+  {
+    TREE_DEPTH_MULTIPLIER = 10000,
+  };
   /**
    * @brief The sort function type.
    *